Angela Sofíá Osorio
Tiempo de lectura 3 minutes
Fecha de publicación
Los oscuros días de crear duplicados infernales de archivos HTML o depender de librerías externas inestables terminaron. Astro ya cuenta con enrutamiento de internacionalización (i18n) de forma nativa en su núcleo. Funciona rápido, sin fricciones y es sorprendentemente lógico.

Vamos a configurar un sitio multilingüe en Astro desde cero utilizando la documentación oficial. Olvida las soluciones temporales; hoy escribimos código listo para producción.
1. Dile a Astro qué idiomas hablas
El primer paso ocurre en el cerebro de tu proyecto: el archivo de configuración. Aquí definimos las reglas de enrutamiento y los idiomas soportados. Astro no adivinará tus intenciones.
Abre el archivo y añade el objeto i18n.
// astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
i18n: {
defaultLocale: 'es',
locales: ['es', 'en', 'fr'],
routing: {
prefixDefaultLocale: false
}
}
});
JavaScriptLa propiedad prefixDefaultLocale: false es una decisión estratégica. Significa que tu dominio raíz cargará directamente en español, mientras que el inglés y el francés usarán las subrutas /en/ y /fr/. Tus métricas de SEO agradecerán esta estructura.
2. Reorganiza tu arquitectura de rutas
Astro depende de un enrutamiento estricto basado en archivos. Si quieres renderizar páginas en inglés, necesitas forzosamente un directorio en inglés. Tu carpeta src/pages/ requerirá un rediseño menor.
Crea directorios específicos para tus idiomas secundarios. El contenido del idioma predeterminado puede quedarse tranquilo en la raíz.
src/
└── pages/
├── index.astro // Ruta: / (Español)
├── en/
│ └── index.astro // Ruta: /en/ (Inglés)
└── fr/
└── index.astro // Ruta: /fr/ (Francés)
JavaScript3. Construye tu diccionario de la interfaz
Codificar cadenas de texto duro directamente en las plantillas es un crimen de mantenimiento que no vamos a cometer. Centralizaremos nuestras traducciones para mantener el código limpio.
Crea un archivo TypeScript dedicado exclusivamente a almacenar tu texto estático.
// src/i18n/ui.ts
export const languages = {
es: 'Español',
en: 'English',
fr: 'Français',
};
export const defaultLang = 'es';
export const ui = {
es: {
'nav.home': 'Inicio',
'nav.about': 'Acerca de',
},
en: {
'nav.home': 'Home',
'nav.about': 'About',
},
fr: {
'nav.home': 'Accueil',
'nav.about': 'À propos',
}
} as const;
TypeScriptAñadir as const al final es un excelente truco de TypeScript. Congela el objeto en memoria y habilita un autocompletado exacto cuando estemos escribiendo nuestros componentes.
4. Fabrica el motor de traducción
Ahora necesitamos un mecanismo que detecte el idioma actual analizando la URL y extraiga la palabra correcta del diccionario. Crea un archivo de utilidades separado para esta lógica.
// src/i18n/utils.ts
import { ui, defaultLang } from './ui';
export function getLangFromUrl(url: URL) {
const [, lang] = url.pathname.split('/');
if (lang in ui) return lang as keyof typeof ui;
return defaultLang;
}
export function useTranslations(lang: keyof typeof ui) {
return function t(key: keyof typeof ui[defaultLang]) {
return ui[lang][key] || ui[defaultLang][key];
}
}
TypeScriptLa belleza de este código reside en su red de seguridad. Si olvidas traducir un término específico en francés, la función useTranslations regresará silenciosamente al texto predeterminado en español. Cero pantallas en blanco para el usuario.
5. Inyecta los textos en tus componentes
Llegó el momento de ensamblar las piezas. Abre cualquier página .astro dentro de tus nuevos directorios e importa las utilidades que acabamos de crear.
El script frontal del componente interceptará la URL global a través de Astro.url y preparará la función de traducción antes de renderizar el HTML.
---
// src/pages/en/index.astro
import { getLangFromUrl, useTranslations } from '../../i18n/utils';
const lang = getLangFromUrl(Astro.url);
const t = useTranslations(lang);
---
<html lang={lang}>
<head>
<title>{t('nav.home')}</title>
</head>
<body>
<nav>
<a href="/">{t('nav.home')}</a>
<a href="/about">{t('nav.about')}</a>
</nav>
</body>
</html>
AstroEl texto ahora responde dinámicamente al contexto. Esta base soporta escalar tu sitio a cincuenta idiomas distintos sin obligarte a modificar la lógica subyacente de la interfaz.
Contents