How to split your i18n file per lazy loaded module with ngx-translate?

Fabien

tl;dr Check the summary section at the end


After a few months of working on my Angular app, my i18n files have more than 800 lines each, almost impossible to maintains and will become more and more difficult with time. The best solution to this problem would be to have one i18n file per module (in fact 2, I have to support French and English).

Environment:

@angular/core@4.4.3
@ngx-translate/core@8.0.0
@ngx-translate/http-loader@2.0.0

The principle

To be able to load a json file along with a lazy loaded module you have to use the property isolate as the documentation suggests. Isolating your TranslateModule will allow you to create a new instance of TranslateService, and, with it, a new HttpLoader instance with a different path to i18n files.

Now, the biggest difference you have to keep in mind is that when you change the language you have to change it for all instanceof TranslateService. This will tell the service fetch the json file of each lazy loaded module for the language you want.

In my code, I use Redux (ngrx-platform) to communicate the language change between all my modules.

Multiple requests?

Note: You have to keep that in mind: this will significantly increase the amount of request made to your server! if you have 10 modules, it’s 10 requests only for translations!

But in 2017, that’s not a problem anymore…

The impact on your performance should will be insignificant.

Folder structure

My assets folder for i18n files looks like this:

assets/
└── i18n/
├── app/
│ ├── en.json
│ └── fr.json
└── home/
├── en.json
└── fr.json

app contains core i18n translations, like: menu, header, footer, and other folders like home, which contain i18n translations for lazy loaded module.

Code

AppModule

First prepare your AppModule to call forRoot() of TranslateModule and to load your core i18n files app/(en|fr).json

AppComponent

AppComponent is your root component, where the user can set the language by clicking on a button in the header. Then you dispatch the language information to your store to let your other modules know that the language has changed and they must change the language of their TranslateService instance.

HomeModule (lazy loaded module)

In this module, declare a new instance of TranslateHttpLoader to get your i18n files home/(en|fr).json

HomeComponent

The only thing left is to call use() of its TranslateService instance, each time the language changes, in all your lazy loaded modules’ components by subscribing to the current language property of your store.

Summary

That’s it! You are now setup to split your big i18n file into more smaller one that will help you to easily maintain your translations file.

To summarize:

  1. In your AppModule call forRoot()
  2. In all your lazy loaded modules call forChild() with isolated: true and create a new instance of TranslateHttpLoader with the path to the i18n files for the module
  3. In all your lazy loaded module’s main component call use() of TranslateService each time the user changes the language

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade