Skip to content

Enabling Angular i18n native

Minko Gechev edited this page Oct 11, 2016 · 14 revisions

Using Angular i18n native module can be tricky. This guide intends to help you enable i18n with the seed and deal with common problems related to internationalization in Angular.

  1. Uncomment src/client/app/i18n.providers.

  2. Enable i18n in the seed

Open main.ts located at src/client/app and uncomment the following lines :

import { TranslationProviders } from './i18n.providers';

...

let TP = new TranslationProviders();
TP.getTranslationFile().then((providers: any) => {
   const options: any = { providers };
   platformBrowserDynamic().bootstrapModule(AppModule, options);
});
  1. The i18n attribute

The i18n attribute is the way Angular determines what content is to translate. It also helps the compiler-cli to generate the XLF file. For example:

<h1>Howdy!</h1>

<!-- becomes -->

<h1 i18n>Howdy!</h1>

WARNING: translatable fields are ids based. Since the ids is based on the content of the element (formatting and text), make sure to avoid any breaking returns, empty lines, etc. If so, the translation will break when the application is mangled for production.

  1. Generate your XLF base file

In the command line, run the following command:

$ npm run i18n

This will generate a messages.xlf at the root directory. Move this file to your locale folder (default folder is set to src/client/assets/locale. Copy it and rename it such as messages.fr.xlf for french, messages.de.xlf for german, etc.

By convention, we respect the ISO 3166-1 alpha-2 2 letter country code names.

  1. Manage the application language from the client

    Open i18n.providers.ts located at src/client/app, this is where you will set the way you want to deal with languages, there is no default but a noProviders callback is local language is undefined.

    The seed lets you manage languages the way you want. Here is working example for you to try:

    Replace the following lines from the i18n.providers.ts files:

...

// Define a way to retrieve the local information let locale: string = localStorage.getItem('lang') || 'en-US';

...


To create the localStorage record, open `navbar.component.ts` located at `src/client/app/shared/navbar` and update the component such as:

```ts
export class NavbarComponent {
  public lang: string;

  public constructor () {
    this.lang = localStorage.getItem('lang') || 'en-US';
  }

  public selectLanguage = (lang: string) => {
    localStorage.setItem('lang', lang);
    window.location.href = '/';
  }
}

Finally, edit navbar.component.html and add the following lines in the <nav> element:

<a (click)="selectLanguage('fr')" *ngIf="lang !== 'fr'">Français</a>
<a (click)="selectLanguage('en-US')" *ngIf="lang !== 'en-US'">English</a>
  1. Compiling for AoT

    While JiT does not require any action to compile a multilingual application, AoT is different. One needs to generate one package per language using the following command (example for french) :

$ npm run build.prod.exp -- --lang fr


> At the moment, the compiler will only recognize files stored in `src/client/assets/locale/messages.xx.xlf`.

6. Known issues

#### A. Translation break at runtime in production environment
*Issue:* When the compiler scans for i18n elements, it also gives a specific id to the translatable field. This id is based on the content and the formatting of the field. When building, the `build.prod` task will mangle the text nodes which result in creating different ids between dev and prod environment. This issue should disappear with AoT.

*Solution:* Make sure to keep your text inline.

#### B. The language won't change
*Issue:* The language file cannot be found or the Translation for id="xxx" cannot be found.

*Solution:* Make sure `i18n.providers.ts` data is correct (translation filenames and translations folder).


> More information about `I18nSelectPipe` and `I18nPluralPipe` to come.

7. In order to allow `ng-xi18n` find the application, in `tools/tasks/project` create file called: `app.through.ts` with the following content:

```ts
import '../../../src/client/app/main';

That's all folks. This guide helped through the process of enabling i18n native.