Tutorial: Angular & Internationalization

Introduction 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 […]

by Christian Fritz

October 26, 2021

6 min read

binary g31a7b663c 1920 - Tutorial: Angular & Internationalization

Introduction

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.

Scenario

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.

dKW i K05oLFLwSkPgyzSBvgwmvdKfm6tghVjrdLpdjFsNrU2BmdrSXUqWR4eZEhtB3FZqkPjN8yg2I1hzfCdiif6dev fx8BIf5ToVuL31lVxkO6sCv Ku - Tutorial: Angular & Internationalization

The Basics

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:

image 5 - Tutorial: Angular & Internationalization

After this, we can place them in the app.component.html:

image 6 - Tutorial: Angular & Internationalization

Once we run

>> ng serve

and open localhost:4200 in the browser, it looks like this:

FxKLxtSBHgZwbyl82E - Tutorial: Angular & Internationalization

This does not yet look like in the wireframe, so we add Material’s Card component and include two courses with dummy data:

17hnRL eXWArQFYltV93wVUQ6UHo7yw8ZnVbu3 hPfIXdfjwkG2VX4kZMIrf31TZHSr 3 E9nQNJoFgSndvK rX5x95iCqC70PUZoSPt29B5I nTchlmTT9ZRY 1lCSFVwF38 us1600 - Tutorial: Angular & Internationalization

You can find the source code for this demo application in GitHub.

Comparison

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.

Built-In Internationalization

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:

image 7 - Tutorial: Angular & Internationalization

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

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:

pZOyJ6ISL 7Nz0hCfIWeErCkSCaPuQzwAaUUPplwtad6lCy2GUHUq1Erm1BTBp - Tutorial: Angular & Internationalization

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:

image 8 1 - Tutorial: Angular & Internationalization

And here you can see the keys in bg.json:

image 9 1 - Tutorial: Angular & Internationalization

We need to configure the TranslateModule and the http-based loader in the app.module.ts:

image 10 - Tutorial: Angular & Internationalization

Afterwards, we can modify the html template and make use of the translate pipe:

image 11 - Tutorial: Angular & Internationalization

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.

image 13 - Tutorial: Angular & Internationalization

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:

image 14 - Tutorial: Angular & Internationalization

After this, we can implement the language switching logic in the typescript file:

image 15 - Tutorial: Angular & Internationalization

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:

image 16 - Tutorial: Angular & Internationalization

The result should look like this:

p2cEUSOBdkQWiaZkpQDa BqWqxbQAUgwZZYoSXinWinWLzvnDQ9GU29k1yBUyrMbl kmP6x3BUoyLS57l - Tutorial: Angular & Internationalization

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:

image 17 - Tutorial: Angular & Internationalization

Additionally, we need to add the following imports:

image 18 - Tutorial: Angular & Internationalization

Afterwards, we register the two locales in the constructor:

image 19 - Tutorial: Angular & Internationalization

The following screenshot shows that the date pipe is adapting to the changed locale.

ltMz4A3BZfvbSQIiOh0ls3c2g6zAYnM8zUImxFiMktQer2p2NGI4WksaJsXCNxO - Tutorial: Angular & Internationalization

You can find the complete source code in this branch on GitHub.

i18next

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.

Conclusion

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!

Software Developer and Team Lead at Dreamix