In this article, we will create a demo Angular application and implement the option to switch between two languages. We will evaluate different internationalization libraries for Angular and see their advantages and drawbacks. We will use the latest Angular version – if you are interested in how internationalization can be achieved with AngularJS, then read this blog article.
Let’s quickly sketch a small scenario to make our research feel a bit less theoretical.
The fictional company IT Sports is offering various sports courses in the Bulgarian capital. Their customers are Bulgarians and foreigners, that’s why they want to offer information about the courses in different languages. For a start, they accept a static page which needs to be redeployed in case the course information changes, but in the future, they want to allow customers to register and the course information to be editable.
The initial wireframe contains just a small welcome text, the upcoming courses and the possibility to switch the language in the upper right corner.
We will use the most recent Angular version (which is 12.2 as of October 2021). In terms of IDE, I used Visual Studio Code, which is lightweight and sufficient for the application’s needs.
We start a new project by using the command
>> ng new it-sports
Before even implementing the first page – let’s choose a UI component framework. There are many articles on the Pros and Cons of Bootstrap and Angular Material and both would be perfectly fine for this use case. For now, we are choosing Angular Material, because it might have an even easier integration with Angular.
With this decision made, we can set up our first page after adding the new library and selecting our favourite color combination during the installation process.
>> ng add @angular/material
Each material component we want to use in the application needs to be imported in app.module.ts:
After this, we can place them in the app.component.html:
Once we run
>> ng serve
and open localhost:4200 in the browser, it looks like this:
This does not yet look like in the wireframe, so we add Material’s Card component and include two courses with dummy data:
You can find the source code for this demo application in GitHub.
Now that we have our first page set up, we can start experimenting with different internationalization libraries. Generally, it’s a good idea to introduce internationalization before too many labels in your UI are already hard-coded. For Angular, the options we are looking at are the built-in Angular Internationalization, ngx-translate and i18next.
Like all other Angular features, the built-in Angular Internationalization comes with a detailed developer guide. We can install it via
>> ng add @angular/localize
A huge benefit of this solution is the ability to annotate your labels with meta information. If a third party performs the translation, this helps to understand the context and find the right expressions in the target language. To indicate that an element needs to be translated, we just add i18n with the optional description:
Note that we are not working with message keys here. You can implement the whole application with English labels and you immediately know the content without having to look up keys in json or properties files – very developer-friendly!
We can generate xml-based files which can be used to provide translations to other languages with the command
>> ng extract-i18n
However, the Developer Guide suggests to deploy the localized versions of the app in different subdirectories and redirect the user based on the HTTP-header. Since we want to dynamically switch the language via UI without reloading the whole page, this does not meet our requirements.
ngx-translate is the most minimalistic library of the three candidates. It uses message keys and json files to store the translations for different languages.
In order to install ngx-translate, we need to run the following commands
>> npm install @ngx-translate/core
>> npm install @ngx-translate/http-loader
and create a folder structure in the assets folder of our project:
Now we can start the translation process with the two languages. The json can be structured hierarchically, for example, by sections.
This is how the beginning of en.json looks like:
And here you can see the keys in bg.json:
We need to configure the TranslateModule and the http-based loader in the app.module.ts:
Afterwards, we can modify the html template and make use of the translate pipe:
Running this will lead to the exact same output in the browser as before, as English is configured as the default language.
Let’s quickly allow the user to change the language by adding a dropdown menu inside the navigation bar.
To keep the button on the right side of the screen, we add a spacer-element, which we need to define in the app.component.scss:
After this, we can implement the language switching logic in the typescript file:
Note that we do not have to reference the files directly, ngx-translate finds them for us.
Finally, we have to add two new imports in app.module.ts to make it compile:
The result should look like this:
There’s only one problem left to solve – as you can see, the date is not converted to the Bulgarian format. Luckily, the Angular date pipe already supports different locales, so we just need to make use of its optional parameters:
Additionally, we need to add the following imports:
Afterwards, we register the two locales in the constructor:
The following screenshot shows that the date pipe is adapting to the changed locale.
You can find the complete source code in this branch on GitHub.
i18next offers support for many different frameworks and platforms and is much more flexible than the other two solutions. If you are looking to define translations based on a parameter (e.g. “you received X new messages” where X is “no” for 0, “a few” for 2-10 and “many” for more than 10 messages), i18next is preferable over ngx-translate. For our example, we want to see if we still can configure it easily to work with such an unpretentious demo application.
For the easiest integration with Angular, we have to install three packages:
>> npm install i18next
>> npm install angular-i18next
>> npm install i18next-http-backend
The good news is that we can reuse the json files which we have created before. The setup is very similar to ngx-translate: We have to perform configurations in app.module.ts, import a service in the typescript file to change the language and use a pipe for the translation. Note that we cannot use the default pipe i18next as it is a pure pipe, and it does not detect the change of the language. Therefore, we have to use its impure version i18nextEager. For the sake of brevity, I won’t list all the changed files here, but you can see the whole code for the implementation in this GitHub branch. The running application in the browser looks identical.
We analyzed three different solutions to internationalization with different strengths and drawbacks. For our particular scenario, ngx-translate and i18next seem to be more appropriate and are both easy to configure. The built-in internationalization has huge advantages when the translations are provided by a third party. For applications that use multiple platforms, i18next might be most suitable. I hope this article helped to understand internationalization in Angular. Feel invited to share your thoughts or experiences in the comments section!