Translating Angular Applications with Built-In I18n Module

Angular I18n built-in module is steadily evolving, and developers are gradually transferring to it from third-party ngx-translate solution. This article gives an introduction to the I18n module and shows its use-cases.

We have already published a handful of articles covering the process of translating Angular applications, however, they were covering a third-party tool called ngx-translate. This is a great solution, but there is also a built-in Angular I18n module, and it is a recommended choice by the official docs. This module used to have some downsides but it is being constantly updated, and now 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, and 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’s format is more complex, it is also more powerful at the same time.
  • The maintainer of the ngx-translate believes that as soon as the “Angular catches up”, his solution will be deprecated. This person was actually hired by the Angular team to work on the I18n  module, and 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! In this article 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’s create a new sample application. Before running the command below, however, make sure that you have Angular 6 or  higher:

If your business is worldwide (be it an online store, a music app, or a social network), it is really important to localize it properly. Let’s 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,  there is also the description and the context. Remember that the 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, so the translation file with all the extracted messages was created. But how do we actually translate something? It is very simple indeed! All you need to do is find the source tag that contains the initial message, and place a target  tag beneath it with the translated text:

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:

Don’t forget to replace the TranslationApp with the name of your own application. Also, find 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, 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 his 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 utilize 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 are going to see that the placeholder is translated properly now!

Assigning Ids To Translation Messages

Another useful feature is the ability to define ids for your translation messages and use 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 utilized two times. Now add source to the trans-unit and make sure that this translation is displayed for both messages:

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

Working With Select Input

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:

Now the options for the select input are 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 to create multiple versions of your application, one per locale. Let’s build the Russian version of the application:

Here is the 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 take 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 server, and enjoy your multi-language application.

PhraseApp and Translation Files

Working with translation files is hard, 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 PhraseApp can make your life easier!

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


In this article, we have taken a look at Angular I18n module and seen it in action. You have 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 surely it will 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 I18n module over ngx-translate? Share your thoughts in the comments! I thank you for staying with me, and until the next time.

Translating Angular Applications with Built-In I18n Module
4.7 (93.33%) 3 votes
Related Posts