Translating Angular Applications with a Built-In I18n Module

Localize Angular

The Angular I18n built-in module is steadily evolving, and developers gradually transfer to it from third-party ngx-translate solutions. Let us take a look at its particularities and use-cases.

We have already published a handful of articles on the process of translating Angular applications. However, they usually cover a third-party tool called ngx-translate. While this is a great solution, there is also a built-in Angular I18n module – and it is a recommended choice by the official docs. The module used to have some downsides, but it is being constantly updated, so it has become a solid tool suitable for both small and large applications. You may refer to this GitHub discussion, where the ngx-translate author talks about the future of his solution. In a nutshell, the situation is as follows:

  • Initially, the built-in I18n module had some issues, so ngx-translate was created to overcome them.
  • The built-in module only supports XML, while ngx-translate by default works with JSON and allows to write custom loaders. However, as we are going to see, even though the built-in module is format is more complex, it is also more powerful at the same time.
  • The maintainer of ngx-translate believes that as soon as Angular “catches up”, his solution will be deprecated. In fact, this person was hired by the Angular team to work on the I18n module; he states that the built-in solution is much more complex and bug-free.

So, while ngx-translate is still being widely used, you should think about transferring to the built-in module sooner or later. Therefore, in this article, I am going to introduce you to this tool and show what goodies it has to offer! We are going to see various examples of using I18n: extracting translations, working with pluralization and gender data, translating placeholders, select boxes etc. Shall we start?

Starting a Demo App

To see the I18n module in action, let us create a new sample application. However, before running the command below, make sure that you have Angular 6 or higher:

If your business is global – be it an online store, a music app, or a social network – it is really important to localize it properly. Let us see how you can introduce support for I18n in your app. For simplicity, open the src/app/app.component.html file and replace all the contents inside with the following:

This instructs Angular to translate the given message to the currently set language. Note that this i18n attribute is not a directive and it will be removed after the translation is performed.

Unfortunately, having a text to translate may not be enough. There is even a joke about translators: “– Are you a translator? Then please say something as a translator! – Well, I need to know a context…”. And this is very true: In unobvious cases, translators require context, and it is possible to provide it with the help of the i18n attribute:

Here, we are providing both meaning (“greeting”) and description (“message appears for new users of the application”) for the message. If two messages have the same meaning, they are going to have the same translations. Note that the meaning and description have to be separated with the pipe symbol (|).

Extracting Messages

Now, where do we provide the actual translations for the messages? Of course, there is a special file for that, but, luckily, we do not have to create it manually. Instead, run the following command:

I will be adding support for the  Russian locale, therefore I have ru set for the i18n-locale option and set as the output file. You may replace this language code with another one.

The above command is going to generate a new file inside the src/locale folder:

This is a XLF format is based on XML and, frankly,  it looks quite ugly – well, at least if you got used to JSON or YAML. Still, it is quite powerful, so just go with it.

Note that here we have our messages extracted from the app/app.component.html file. For each message, we see the filename and even the line number where it is located. For the second message, we also have both description and context. Remember that contains translations only for the Russian language, and in order to support additional locales, a separate file has to be generated.

Performing Translations and Configuring Locale

Okay, the translation file with all extracted messages has now been created. But how do we actually translate something? It is actually very simple! All you need to do is find the source tag that contains the initial message, and place a target tag with the translated text just beneath it:

Do the same for the second message (and mind the context when performing translation!):

Good job. The next step is to set up the ahead-of-time compiler (typically used for production). Open the angular.json file, find the serve property and add the following to the  configurations:

Do not forget to replace the TranslationApp with your own application’s name. Find also the build property and append the following inside the configurations:

This basically enables AOT and tells where to find the translation file, what format it has and which locale it contains.

By default, when you start the application, the English locale is being used, but this can be changed by providing the following argument:

After this command is run, navigate to localhost:4200 and note that all the text is in Russian.

I18n Module Usage Examples

Working With Date and Time

In order to localize datetime, you may utilize a special pipe operator that does not require the i18n attribute at all. Suppose we have a today variable containing the current date:

I would like to display this datetime but in a localized format. Tweak the src/app/app.component.html:

Here, we are localizing the given datetime and displaying it using a medium format. Angular has support for many locales out of the box, and you do not need to provide datetime translations manually.

Performing Pluralization

Pluralization rules differ from language to language, and therefore you have to take care of all potential cases. For example, let’s introduce two users and store their count:

Now I would like to display this count while using the proper from of the “пользователь” Russian word (which means “user”). Place the following code inside the app.component.html:

  • The first parameter usersCount is bound to the usersCount property defined above
  • The second parameter plural sets the translation type
  • The third parameter lists all the possible cases (when there are 0, 1, few, or more users) and the corresponding text to display. Angular supports a handful of categories listed here.

Now add the following contents to the  file:

The main thing here is the second target that contains translation for all the possible cases  (note that we also interpolate the value of the usersCount in some cases).

In order to observe this feature in action, add a simple button that increments the usersCount  by  one  on each click:

Now keep clicking on this button and note that upon reaching a certain number, the text changes automatically!

Working with Gender

It is also possible to use a  select translation type which, for example,  can come in very handy when working with gender data.  Suppose I would like to display the first user’s name and say either “Mr.” or “Ms.” depending on the gender:

Add translations to the file:

As you can see, this is very similar to what we did when doing pluralization.  Of course, you may use this approach not only when working with gender information but for other cases as well.

Translating Placeholders

What’s interesting, there is even a special attribute to translate placeholders for inputs. Use  them in the following way:

And then add translation as usual:

You’ll see that the placeholder is translated properly now!

Assigning ids to Translation Messages

Another useful feature is the possibility of defining ids for your translation messages and using them throughout the application. If the same id is used for multiple messages, it will be extracted only once, and the same translation will be applied. Take a look at the following example:

Here, we have two different messages, but as long as they have the same id (prefixed with @@), the translation will be the same. Also, if you now extract these messages to the .xlf  file, you’ll see the following:

trans-unit has the sampleText id (compare it to the random gibberish used for other translations), and there is only one source. Still, we see that there are two context groups because this id is used two times. Now add source to the trans-unit and make sure that this translation is displayed for both messages:

Such an approach is very useful when you do not want to duplicate the same translation multiple times (don’t repeat yourself!).

Working with Select Input

The I18n module is clever enough to support select input as well. Suppose, you have a dropdown with four options:

We do not want to translate the value but the display text should be localized properly. It can be done with the following code:

The options for the select input are now localized properly, while the values sent to the server are left intact!

Preparing For Deployment

So, your application is translated and you would like to build it. How do you do that? Well, it appears that Angular allows creating multiple versions of your application, one per locale. Let’s build the Russian version of the application:

Here is a brief explanation of this command:

  • The output path is dist/ru
  • We are using AOT compiler
  • We are building for production
  • This version should be accessible via the /ru/ URL
  • The translation file is taken from the src/locale folder
  • The translation file has a format of XLF
  • The locale is Russian

This is it! You may perform this command for all other locales, then push to the server, and enjoy your multi-language application.

Phrase and Translation Files

Working with translation files is not easy, especially when the app is big and supports many languages. You might easily miss some translations for a specific language – which will lead to user’s confusion. And so Phrase can make your life easier: Grab your 14-day trial.

Phrase supports many different languages and frameworks, including JavaScript of course. It allows to easily import and export translations data. What is cool, you can quickly understand which translation keys are missing because it is easy to lose track when working with many languages in big applications. On top of that, you can collaborate with translators as it is much better to have a professionally done localization for your website.


In this article, we took a look at the Angular I18n module in action. You learned how to get started with this module, how to provide translations and where to store them, how to perform pluralization, work with gender, localize datetime, select boxes and placeholders. As you see, this module is indeed very powerful and it will surely be enhanced even further in the near future. Of course, we have not covered all the features of the I18n module, so don’t forget to check the official documentation.

Do you like this built-in solution? Would you prefer using the I18n module over ngx-translate? Share your thoughts in the comments! Thanks for staying with me, and until next time!

1.8 (35.05%) 101 votes