Internacionalización de Aplicaciones con Angular
Paso a paso aprenderemos a traducir una aplicación de Angular a diferentes idiomas.
En este artículo vamos a aprender a cómo usar el paquete de internacionalización de Angular (i18n), para tener en nuestra aplicación diferentes idiomas disponibles para el usuario.
Recomiendo que antes de la lectura estés familiarizado con Angular, ya que en este caso trabajaremos sobre un proyecto ya creado, y solo trataremos el cómo traducirlo.
A lo largo del tutorial veremos dos partes principales, una es aprender a traducir los textos de la aplicación, y otra usar una librería que nos ayudará a la hora de “mergear” nuevas traducciones.
Se usará Angular 12 para este tutorial.
Índice
⦁ Por qué es importante internacionalizar aplicaciones
⦁ Instalación del paquete de internacionalización de Angular
⦁ Cómo marcar para traducción todos los tipos de texto
⦁ Trabajando con los archivos de traducción
⦁ Librería ngx-i18nsupport
⦁ Producción
⦁ Conclusión
Por qué es importante internacionalizar aplicaciones
Como todos, en nuestro día a día, usamos aplicaciones que fueron creadas en otros países y en otros idiomas. Y aunque no parezca importante, es uno de los motivos por los que estas aplicaciones se hicieron famosas en todo el mundo.
No todas las personas saben idiomas, y proporcionar versiones de tu aplicación en distintos lenguajes hará que llegue al mayor número posible de usuarios.
Mejorar la experiencia del usuario siempre es un punto importante.
Instalación del paquete de internacionalización de Angular
Antes de hacer nada, tenemos que asegurarnos de que tenemos el paquete de internacionalización de Angular, si no lo tenemos, se añade de la siguiente manera a nuestro proyecto:
ng add @angular/localize
Antes de continuar debemos fijarnos en una cosa, y es que los idiomas son identificados por un código, por ejemplo, el español se identifica con es
y el francés con fr
. El idioma predeterminado de Angular es en-US
, es decir, el inglés de Estados Unidos, por eso debemos editar el archivo angular.json
y cambiarlo por es
, ya que en este caso, empezaremos con el español como idioma principal.
Cómo marcar para traducción todos los tipos de texto
A continuación, lo único que debemos hacer es ir al archivo HTML que queremos traducir, e ir añadiendo la propiedad i18n
a las etiquetas que elijamos.
Como puedes ver en el código, todas aquellas etiquetas que tienen texto han sido marcadas con la propiedad i18n
. Algunas con una pequeña descripción, esto no es obligatorio, pero sí recomendable ya que añadir una descripción siempre va a ayudar al traductor.
Por otro lado, también podemos marcar para traducción propiedades que ya existen en la etiqueta, como placeholder
. Podemos hacer esto con casi todas las propiedades, con i18n-[propiedad]
.
Como has visto, pueden marcarse los textos con interpolación, pero ojo, ¡los nombres de las variables no deben traducirse!
Ahora analicemos esta línea:
<div class="date">{{ today | date }}</div>
Angular nos permite usar una pipe que formateará la fecha automáticamente dependiendo del lenguaje. También existen otras pipes para las divisas o los decimales.
Ahora echemos un vistazo a una traducción algo más compleja, los “plurals”:
<span i18n>Actualizado {minutes, plural, =0 {justo ahora} =1 {hace un minuto} other {hace {{ minutes }} minutos}}</span>
Así a bote pronto puede parecer un lío, pero miremos con calma y entendamos de qué va la cosa. Angular nos da la cláusula “plural”, que se usa para marcar expresiones que pueden no tener sentido si se traducen palabra por palabra.
De este modo, podemos expresar distintos escenarios dependiendo de una variable, en este caso, minutos.
En lugar de dejar un feo “Actualizado hace 1 minutos”, podemos cambiar el texto dependiendo de los minutos, así también será más fácil de traducir.
Trabajando con los archivos de traducción
Bien, ahora que ya hemos marcado todo el texto que queremos traducir, llega la hora de la verdad, traducir.
Para esto, debemos generar unos archivos con los textos que van a ser traducidos, pero no os asustéis, es solo un comando:
ng extract-i18n --output-path src/locale
Esto generará automáticamente un archivo XLF con el texto a traducir. Los archivos XLF están basados en XML, y se crearon para ser un estándar en localización.
Nota: También pueden generarse como JSON, XMB O ARB.
Pero… ¿Y ahora qué hacemos con esto?, pues bien, este archivo se quedará como referencia del idioma original. A continuación debemos duplicar el archivo y cambiarle el nombre a messages.en.xlf
.
De esta forma, ya marcamos ese archivo como la traducción a inglés. Se puede hacer con cualquier otro idioma, por ejemplo a messages.fr.xlf
.
Lo ideal es mandar este archivo a un traductor profesional, pero en este caso somos unos genios de los idiomas y vamos a ver cómo se hace para traducir a mano los textos.
En el archivo podéis ver que el XLF está dividido en partes muy claras, se pueden diferenciar los nodos <trans-unit>
que son cada etiqueta que hemos marcado, junto con el texto original y otros datos.
Para traducirlo, lo que tenemos que hacer es tan sencillo como duplicar la etiqueta <source>
y renombrarla a <target>
en cada trans-unit, dentro escribiremos el texto traducido, tal que así:
También hay que tener en cuenta que los plurals se tratan de forma separada, pero se traducen exactamente igual
Ahora, antes de continuar debemos configurar en el archivo angular.json
los idiomas que vamos a usar en la aplicación y la ruta de su XLF.
Lo siguiente, también en el archivo angular.json
, es definir en las opciones de build
, que la aplicación tenga en cuenta los idiomas que hemos definido anteriormente en locales
, esto nos servirá más adelante en la sección de producción.
Con esto ya estaría todo listo para producir las traducciones, sin embargo, surge un problema. Al definir la propiedad localize
, Angular quiere desplegar todos los idiomas, pero el servidor de desarrollo solo permite un idioma a la vez, por lo que si queremos testear las traducciones, debemos configurar unas opciones de idioma y poder activar el servidor especificando el lenguaje que queremos ver.
Ahora ya podemos iniciar el servidor con el siguiente comando:
ng serve --configuration=en -o
donde en
puede ser cualquier idioma que hayamos configurado.
Librería ngx-i18nsupport
Pues ya tenemos nuestra aplicación localizada a otros idiomas, pero… ¿Qué pasa si quiero seguir trabajando en mi aplicación y por lo tanto añadiendo más contenido que traducir?
Bueno, solo basta con seguir marcando las nuevas etiquetas con la propiedad i18n
como ya hemos aprendido, pero al hacer esto cuando ya hay archivos XLF creados hace que pase algo, y es que al generar las nuevas traducciones, no se actualizan los archivos que ya existen.
El comando extract-i18n
vuelve a generar un archivo XLF totalmente nuevo y con los nodos identificados de forma diferente, así que hay dos soluciones para facilitar el trabajo de mergear los archivos:
- Añadir a cada i18n un identificador único, lo cual puede ser tedioso y caótico en proyectos grandes.
- Usar la librería ngx-i18nsupport, que automatizará todo el proceso.
Podemos instalarla con el siguiente comando:
ng add @ngx-i18nsupport/tooling
Hará algunas preguntas como qué tipo de archivo queremos o cuál es nuestro idioma principal. Una vez instalada, pasamos a lo siguiente.
La instalación hará cambios automáticamente en package.json
y en angular.json
, así que debemos revisarlos para ver que todo sigue a nuestro gusto:
En el archivo package.json
, vemos que se han creado dos nuevos scripts, uno para generar los archivos de traducción y mergearlos automáticamente (a partir de ahora será ese el comando que usemos para las nuevas traducciones), y otro script para iniciar el servidor de desarrollo del idioma inglés.
Pero cuidado, ese comando de extract-i18n
está desactualizado, así que si no quieres advertencias o errores, te dejo el comando actualizado:
"extract-i18n": "ng extract-i18n [nombre-del-proyecto] --format xlf –-output-path src/locale/ && ng run [nombre-del-proyecto]:xliffmerge"
Ahora revisemos el archivo angular.json
:
Vemos que ha añadido una nueva sección llamada xliffmerge
, con una configuración que también debemos editar, hasta que quede algo así:
Eliminamos la propiedad i18nFormat
ya que está en desuso, y editamos las rutas para que coincidan con las que ya teníamos en el proyecto.
También podemos ver que nos ha cambiado la configuración de build
:
Solo tenemos que dejarlo como estaba, borrar todas esas propiedades en desuso o redundantes:
Ahora que ya se adapta a nuestro proyecto, lo único que debemos hacer es añadir nuevas traducciones, y lanzar el comando:
npm run extract-i18n
Al acabar nos avisará de que hay nuevas líneas para traducir en el archivo XLF correspondiente.
Como ves, las nuevas líneas son marcadas con una propiedad state="new"
. Solo tenemos que traducirlo como siempre y borrar la propiedad state
para no confundirnos en el futuro, y ¡listo!, ya tenemos todo hecho para tener una aplicación internacionalizada.
Producción
Ahora que tenemos nuestra aplicación lista, falta un tema importante, ¿qué hacemos para pasarla a producción, y servir todos los idiomas?
Lo primero que hay que hacer, obviamente, es buildear la aplicación:
ng build –-configuration production
Y veremos que en el resultado final se crean dos directorios, en
y es
.
No hay más misterio que llevar la aplicación al servidor que queramos y configurarlo un poco, aquí os dejo un enlace con la información necesaria para Apache y Nginx:
Conclusión
Como podéis ver, internacionalizar una aplicación en Angular es muy sencillo, y es algo que se debe tener siempre en cuenta para que todos los usuarios puedan disfrutar de ella.
Si te ha gustado y te ha parecido útil, por favor, ¡No dudes en compartir! Muchas gracias por leer.
Os dejo el repositorio que he usado para desarrollar la aplicación de prueba:
https://github.com/rubencfu/angular-i18n-example
Y también más información sobre i18n en la página de Angular: