Documentation Index Fetch the complete documentation index at: https://mintlify.com/abisai7/diccionario-chapin/llms.txt
Use this file to discover all available pages before exploring further.
The Chapinismos project supports multiple languages (Spanish and English) through a custom internationalization system built with Astro’s dynamic routing.
Translation System
Translations are managed in a centralized file at src/utils/i18n.ts. The system uses a simple key-value object structure for each language.
Translation Object Structure
export const translations = {
es: {
"home.title" : "Chapinismos - Diccionario de Palabras Guatemaltecas" ,
"home.description" : "Diccionario completo de chapinismos..." ,
"search.title" : "Buscar" ,
"nav.home" : "Inicio" ,
// ... more translations
},
en: {
"home.title" : "Chapinismos - Guatemalan Slang Dictionary" ,
"home.description" : "Complete dictionary of Guatemalan slang..." ,
"search.title" : "Search" ,
"nav.home" : "Home" ,
// ... more translations
},
};
Core i18n Functions
getLangFromUrl()
Extracts the language from the URL pathname.
export function getLangFromUrl ( url : URL ) : "es" | "en" {
const [, lang ] = url . pathname . split ( "/" );
if ( lang === "en" ) return "en" ;
return "es" ;
}
Usage:
const lang = getLangFromUrl(Astro.url);
// Returns "es" or "en" based on URL like /es/buscar or /en/search
useTranslations()
Returns a translation function for the specified language with support for variable interpolation.
export function useTranslations ( lang : string | undefined ) {
return ( key : string , vars ?: Record < string , string | number >) => {
const locale = ( lang === "en" ? "en" : "es" ) as "es" | "en" ;
let text = translations [ locale ][ key as keyof typeof translations . es ] || key ;
if ( vars ) {
Object . entries ( vars ). forEach (([ varKey , value ]) => {
text = text . replace ( `{ ${ varKey } }` , String ( value ));
});
}
return text ;
};
}
Usage in Astro components:
---
import { useTranslations } from "../../utils/i18n" ;
const { lang } = Astro . params ;
const t = useTranslations ( lang );
---
< h1 > { t ( "search.title" ) } </ h1 >
< p > { t ( "index.subtitle" , { count: 150 }) } </ p >
getLocalizedPath()
Generates localized URL paths with language prefixes.
export function getLocalizedPath ( path : string , lang : string ) : string {
const prefix = lang === "en" ? "/en" : "/es" ;
return ` ${ prefix }${ path } ` ;
}
Usage:
const searchPath = getLocalizedPath ( "/buscar/" , "en" );
// Returns: "/en/buscar/"
Dynamic Routing
Pages use Astro’s [lang] dynamic parameter to generate static routes for each language.
Example from src/pages/[lang]/buscar.astro:
---
export const prerender = true ;
export async function getStaticPaths () {
return [{ params: { lang: "es" } }, { params: { lang: "en" } }];
}
const { lang } = Astro . params ;
const t = useTranslations ( lang );
const collectionName = lang === "es" ? "words-es" : "words-en" ;
const allWords = await getCollection ( collectionName );
---
This generates:
/es/buscar/ (Spanish)
/en/buscar/ (English)
Translation Categories
Translations are organized by feature area:
Category Keys Purpose home.*Title, description, search, about sections Homepage content search.*Search UI, results, categories Search functionality word.*Definition, examples, synonyms Word detail pages nav.*Navigation links Site navigation schema.*SEO metadata Structured data
Variable Interpolation
Translation keys support variable interpolation using {variableName} syntax.
Translation definition:
"index.subtitle" : "Explora las {count} palabras del diccionario"
Usage:
{ t ( "index.subtitle" , { count: allWords . length }) }
// Output: "Explora las 150 palabras del diccionario"
Adding New Languages
Add translations object
Add a new language object to the translations export in src/utils/i18n.ts: export const translations = {
es: { /* ... */ },
en: { /* ... */ },
pt: { // Portuguese example
"home.title" : "Chapinismos - Dicionário de Gírias Guatemaltecas" ,
// ... all other keys
},
};
Update type definitions
Update the return type of getLangFromUrl() to include the new language: export function getLangFromUrl ( url : URL ) : "es" | "en" | "pt" {
const [, lang ] = url . pathname . split ( "/" );
if ( lang === "en" ) return "en" ;
if ( lang === "pt" ) return "pt" ;
return "es" ;
}
Add to getStaticPaths()
Update each page’s getStaticPaths() function to include the new language: export async function getStaticPaths() {
return [
{ params: { lang: "es" } },
{ params: { lang: "en" } },
{ params: { lang: "pt" } },
];
}
Create content collections
Create a new content collection for the language:
SEO Integration
Translations are used in meta tags and structured data:
< Base
title = { t ( "search.title" ) + " — " + t ( "schema.site.name" ) }
description = { t ( "search.description" ) }
keywords = { t ( "search.keywords" ) }
lang = { lang }
alternateUrls = { {
es: "/es/buscar/" ,
en: "/en/buscar/" ,
xDefault: "/es/buscar/" ,
} }
/>
This generates proper hreflang tags and localized Open Graph metadata.
Client-Side Translations
For client-side JavaScript, translations are passed via define:vars:
< script
is:inline
define:vars = { {
searchTranslations: JSON . stringify ({
noResults: t ( "search.noResults" ),
tryAnother: t ( "search.tryAnother" ),
categories: {
sustantivo: t ( "search.category.sustantivo" ),
verbo: t ( "search.category.verbo" ),
},
}),
} }
>
const t = JSON . parse ( searchTranslations );
console . log ( t . noResults ); // Accessible in client JS
</ script >
Best Practices
Use consistent key naming
Follow the pattern section.subsection.key for organization:
home.search.placeholder
search.category.sustantivo
word.definition
Keep default language as fallback
The system defaults to Spanish (es) if an invalid language is detected, ensuring content is always displayed.
Ensure every user-facing string has entries in both es and en objects to prevent missing translations.
Use variables for dynamic content
For counts, names, or other dynamic values, use variable interpolation instead of string concatenation: // Good
t ( "index.subtitle" , { count: 150 })
// Avoid
"Explora las " + count + " palabras"