Aquí una “guía” de como implementar i18n en Astro. ¿Pero no existen ya librerias para eso? Pues sí, pero cuando yo las quise implementar no funcionaban, así que tocó crearse la propia. Además, hacerlo tú mismo te hace menos dependiente de terceros.
Tener una página en muchos idiomas es siempre un fastidio, pero a veces es una necesidad si una quiere que su página web sea más accesible. Pero yo me vi en esta necesidad porque me tocó migrar la web de IF7SPORTS de Angular a Astro. ¿Por qué se usó Angular para una página estática? Ni idea, pero tardaba 6 segundos en cargar y eso no era bueno. En el blog de la web escribí un muy pequeño artículo sobre la migración, os lo dejo aquí. La web también tenía diferentes idiomas, pero se usaba un sistema que yo he denominado sistema de idiomas en base a directorios, donde básicamente tienes una carpeta por cada idioma (aunque el idioma por defecto puede ser la carpeta raíz), llegando a una estructura tal que así:
De ello aprendí algo muy importante:
Ni de coña vuelvo a tener que copiar una página entera para que esté en otro puto idioma.
Siempre que se añadía cualquier cosa a la web había que realizarlo mínimo dos veces y era horrible, por eso decidí crear el sistema de idiomas de otra manera, uno que he denominado sistema de idiomas en base a archivos, donde tienes las traducciones en archivos separados.
Si quereis basar vuestra sistema de traducción en directorios y comprobar en carne propia por qué es un atentado contra la humanidad os dejo la receta de oficial Astro de cómo hacerlo aquí.
Cosa importante a decir ahora es que todas las rutas tiene el idioma como prefijo, e.g. /en/home o /es/home, por lo que la ruta raiz no es ningún idioma, e.g. /home es un 404, esto puede ser o no importante dependiendo de lo que buscas. Si quieres intentar hacer que la ruta raiz sea el idioma por defecto te deseo buena suerte y que dios te acompañe :>
Configuración y utilidades
Crea el directorio src/i18n, donde estarán todos los scripts y componentes exclusivos de los idiomas, excepto las traducciones.
Cree la carpeta public/locales y dentro de ella, crea un archivo .json por cada idioma que quieras. En mi caso serán el Inglés, Español y Francés.
En src/i18n/config.ts, añade lo siguiente:
En config.ts se importan las traducciones, se configuran los idiomas, sus locales y se hacen demás cosas útiles.
En el archivo src/i18n/utils.ts, añade lo siguiente:
Por último, puedes añadir algunos import aliases útiles a tu archivo tsconfig.json.
Componentes
Para poder cambiar de idioma, crea el archivo src/i18n/LanguagePicker.astro. Yo os dejo dos opciones: un seleccionable o una lista.
Hay ciertos casos en los que es útil poder establecer etiquetas html invariables a cada idioma sin tener que repetirlo en todos los [language].json, para eso en src/i18n/Trans.astro añade lo siguiente:
Además, tienes que crear el archivo src/i18n/languageTarget.ts.
Para el SEO, crea el archivo src/i18n/I18nHeaders.astro con lo siguiente:
Plantillas
Para que el navegador sepa en que idioma se encuentra la página, es importante añadir el atributo lang en la etiqueta html, para ello añade lo siguiente en el archivo src/layouts/BaseLayout.astro:
Páginas
index.astro
Como comenté al principio, este sistema no está configurado para que la ruta raiz sea el idioma predeterminado, por lo tanto hay que redirigir al usuario añadiendo lo siguiente en src/pages/index.astro:
El problema con esto es que las redirecciones por el lado del cliente son penalizantes para el SEO, por lo que una mejor opción sería usar el modo o hybrid de Astro y cambiar lo anterior por:
[lang]
Las páginas para cada idioma se generan gracias a las rutas dinámicas de Astro, lo único malo es que hay que indicar en todas las páginas los idiomas en los que se va ha traducir.
Crea las traducciones en los [languages].json:
Crea el directorio src/pages/[lang].
En src/pages/[lang]/index.astro añade lo siguiente:
Ahora deberías poder ejecutar npm run dev y tener una página i18n.
Si quieres ver un ejemplo más completo puedes ir a este repositorio, que tiene un blog y usa traducciones en los componentes.