Angular: Introduction to Internationalization (i18n)
A few weeks ago, in one of the many conversations that I share with Martin McWhorter at work (super cool guy that I have the pleasure to work with, that also happens to know a lot about angular), we started discussing internationalization in angular using angular-cli and I decided that it was a great topic for my next article.
Dealing with internationalization is a key aspect when building worldwide applications and most developers have to face dealing with it sooner or later.
Angular provides us with a set of built-in functionalities to deal with internationalization (i18n) (thank you angular!!);
- Displaying dates, numbers, percentages in local formats.
- Translating text in component templates.
- Handling plural forms of words.
- Handling alternative text.
We are going to go through the first two of them in the application that we are going to write in this article. In we are going to discuss a couple of other topics related to internationalization in an angular app.
By default angular uses the locale en-US, to set your application locale to another value use the CLI parameter locale with the proper value that you want to use (note that angular follows the Unicode LDML convention).
For example the command above would serve your application setting the locale to Spanish. You can use the “locale” param with ng-serve and with ng-build.
Let’s start coding!
As I stated earlier we are going to go through some of the key features that angular provides to handle internationalization. We are going to be using angular CLI to create and run the application with AOT compiler (setting and configuring the internationalization for JIT is not part of this article, you can go to the angular documentation for information about internationalization with JIT compiler).
The idea is to create an application that can be built and run with locale set in Spanish or by default in English.
So, first of all, let’s create the application, install angular CLI if you don’t have it yet. After installing angular cli open your favorite console, go to the folder that you are going to use and run the CLI command to create a new project:
Then install all packages using npm install (should have already been executed… but just in case let’s do it again) and run the application using ng serve to see that everything is working ok.
By default angular serves the application with the locale set up to en-US, so let’s use that also as our default and to run the application in Spanish let’s just add an entry to the package.json scripts section:
Using i18n pipes
Angular has a built-in set of pipes to deal with some internationalization issues like dates, decimals, and percentages.
Let’s use datePipe as an example:
In our app.component.html let’s just add a datePipe to show a dateTime property of our component. We are going to pass the ‘long’ property to the pipe to show the long string version of a date.
In the app component let’s just set dateTime to a new Date.
If we run the application now with “npm start” we are going to see the en-US version of a long date.
Let’s run it now with the command “npm run start:es”, now we are going to see the Spanish version of the date rendered.
So this is the main course of our menu, the ability to translate text contained into our templates.
Angular i18n template translation has four phases:
- Mark static text for translation.
- Angular i18n tooling extracts the text into a standard translation source file.
- A translator (or ourselves in this demo) edit that file and return the text in the targeted language.
- The angular compiler uses the translated file to generate a new version of the application with the targeted language.
Let’s go through each of the phases with examples.
Mark static text using angular i18n
We are going to use the angular i18n attribute with a custom id, by doing this every translation unit generated by the i18n extractor tool is more readable and easy to maintain. We are also going to add a description and a meaning to the i18n attribute, this helps angular to improve the accuracy of the translation.
The image above shows how to use this three values in the i18n attribute. First the meaning then a pipe followed with the description. Finally, prefixed with a double at sign the id.
Let’s create a couple of examples in our application:
Great! In the code above we added two examples to our app.component template. One for the app title and one for the home title. We provided a meaning and a description to both.
Use angular i18n tool to extract the text into a file
Now we are going to run the command “ng xi18n” from angular cli to generate the main translation file. This file is going to generate our base translation file called “messages.xlf” in our src folder (you can pass another location or/and name as params to the command).
Now that we have our base translation file we have to create the new language specific translation files. First, we are going to create a folder “locale” under our src folder, where is where our language specific files are going to live.
Let’s copy the recently generated “messages.xlf” file into the locale folder and rename it to “messages.es.xlf” (in our case we are going to have only one file for the spanish translation).
The next step is to edit this new file with the spanish translation
In a real application your company probably hire a translator that should be the one providing the translated version of the files (the description and meaning are going to help this person to get a more accurate translation) but in this example, we are going to do it ourselves.
To do this we need to add a <target> tag after each of the <source> tags in the file. Then we type the spanish version of the text in the target tag.
Great now we have our Spanish internationalization file ready.
Make angular compile in the specified language
We want to be able to build the application in English or in Spanish and we have almost everything set up to get it done.
To get the application in English we just run the “npm start command” that is going to execute an ng serve behind the scenes. So that’s working.
In order to build the application in Spanish we just have to add a couple of params to the Spanish build script in the package.json file.
The first new param is “i18nFile” that points to the location of the Spanish translation file. The second param that we are adding is the “i18nFormat” that refers to the format of the translation file.
Now when we run the command “npm run start:es” we are going to build our application with Spanish translation!
Serving the application
In our example we should have two separated application packages, one with the default language (English) and one in Spanish. We can use different strategies to serve one or another:
- Server-side language detection.
- Url parameters.
Maintaining the translated files
Angular i18n doesn’t provide any functionality to maintain your translated files.
But you can use xliffmerge to maintain and merge your xlfs files. Here is a guide to use it in an angular environment.
Great! Let’s see what we have done
- Configure angular to compile with a different locale.
- Use angular built-in pipes to help us with internationalization.
- Use i18n attributes to provided angular with the information needed for text translation.
- Generate a base translation file.
- Create language-specific files.
- Configure angular to be able to compile the proper language-specific file.
- Point out the strategies to serve the correct application package.
- Point out how to maintain the translated files.
I hope this article helps you understand a little bit more about internationalization with angular!
Here is the GitHub repo.