How to internationalize (i18n) your Angular application? [Tutorial]

Alain Chautard
Angular Training
Published in
4 min readApr 1, 2019

--

The Angular framework itself provides out-of-the-box support for multiple languages and locales. In this post, I’m going to cover how to implement internationalization (shortened as i18n) for your application.

1. Add all of the locales you want to support

This step is required if you want Angular pipes and directives to support default formats from other locales.

Angular uses en-US (English for the United States) as a default locale. Here I’m changing the configuration at the top of app.module.ts to support the locale for the French language in France, which is fr-FR:

import { registerLocaleData } from '@angular/common'; 
import localeFr from '@angular/common/locales/fr';
registerLocaleData(localeFr, 'fr');
// Here you can import more locales if needed

2. Set the current locale

Angular reads the current locale from an injection token called LOCALE_ID. This means you would have to change that token depending on the locale you’re using and provide appropriate dependency injection configuration for it:

providers: [{provide: LOCALE_ID, useValue: 'fr-FR' }]

Note that if you want support for the locale to be changed by the user at runtime, you’ll have to create a class or a factory function to read that value. Here’s an example implementation:

export class DynamicLocaleId extends String {
locale: string;

toString() {
return this.locale;
}
}

...

providers: [
...
{ provide: LOCALE_ID, useClass: DynamicLocaleId }
],

3. Use a translation strategy for all text

Angular supports text translation out-of-the-box through the use of a simple i18n attribute on HTML elements. The only problem with the current approach taken by the framework itself is that it requires one build per language.

As a result, if you have to support five languages, you would need 5 different builds deployed in different folders, which means that switching to a different language at runtime requires a full reload of the application.

That’s the reason why I use ngx-translate to deal with i18n instead:

4. Set-up ngx-translate

ngx-translate is an independent open-source library so the first step is to install it:

npm install @ngx-translate/core --save

In our example, the Angular application is going to download translations from JSON files, which is one of the most common options. That way, translations can be updated and deployed independently from your Angular application.

This requires installing the TranslateHttpLoader for ngx-translate:

npm install @ngx-translate/http-loader --save

By default, ngx-translate will retrieve translations from /assets/i18n/[lang].json where [lang] is the language you’re using, for instance en or fr. This is how you can set-up the translate loader in your app.module.ts:

...
import {TranslateModule, TranslateLoader} from '@ngx-translate/core';
import {TranslateHttpLoader} from '@ngx-translate/http-loader';


// AoT requires an exported function for factories
export function HttpLoaderFactory(http: HttpClient) {
return new TranslateHttpLoader(http);
}

@NgModule({
imports: [
...
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient]
}
})
],
...
})
export class AppModule { }

Note the use of a factory to create the HttpLoader. That’s so that you can customize the loader you want to use. For instance, you can change the full URL to your translation server like so:

export function HttpLoaderFactory(http: HttpClient) {
return new TranslateHttpLoader(http, 'http://mytranslations.com/i18n/');
}

5. Use ngx-translate

The JSON files that store your translations are just a map of keys and values. For instance, here is an example of en.json for the English language:

{
"HELLO": "hello world"
"TITLE": "The title of my app"
}

And the equivalent fr.json for the French language:

{
"HELLO": "bonjour le monde"
"TITLE": "Le titre de mon application"
}

Once you have created those files for all languages, translators will be able to start working and translate all of the texts.

Then you can either use the TranslateService, the TranslatePipe or the TranslateDirective to get your translation values.

With the service, it looks like this:

translate.get('HELLO').subscribe((res: string) => {
console.log(res);
});

This is how you do it with the pipe:

<div>{{ 'HELLO' | translate }}</div>

Finally with the directive:

<div translate="HELLO"></div>

Another option with the directive is to use your HTML element content as a key:

<div translate>HELLO</div>

For more details and options, feel free to take a look at the excellent ngx-translate Wiki page.

The final step is to set a default language for ngx-translate to use. This example gets the default browser language but you can, of course, customize that behavior as long as you pass the language to use using translateService.use(languageCode):

export class AppComponent {
constructor(public translate: TranslateService) {
translate.addLangs(['en', 'fr']);
translate.setDefaultLang('en');
const browserLang = translate.getBrowserLang();
translate.use(browserLang.match(/en|fr/) ? browserLang : 'en');
}
}

And that is it! Now your application can support multiple languages. For a full example that uses a language switcher dropdown, feel free to take a look at the following Stackblitz:

My name is Alain Chautard. I am a Google Developer Expert in Angular, as well as founding consultant and trainer at Angular Training where I help development teams learn and become proficient with Angular.

Need help with Angular? Let’s schedule some time to talk.

If you enjoyed this post, please clap for it or share it. Your help is always appreciated.

--

--