angular-i18n Angular 6 Internationalisation : How to deal with variables

Given the official instructions "translating-plural-and-select-expressions", (overview) can't you do ? :

<div class="title-text" i18n>{currentpage, select, title1 {title1} title2 {title2} unknowntitle {unknowntitle}}</div>

This polyfill seems like the best way to go right now - it's mainly written by Olivier Combe, a member of the Angular team responsible for i18n:

https://github.com/ngx-translate/i18n-polyfill


For Angular 5, you'll need version 0.2.0 when you install:

npm install @ngx-translate/[email protected] --save

For Angular 6, get the latest version - currently 1.0.0:

npm install @ngx-translate/[email protected] --save

I got the polyfill working for both JIT and AOT compilation, for Angular 5 (it will also work for Angular 6). Here's what you need to do to translate to a single language (this is a good way to get this working - you can then get multiple languages working later):

Note on using AOT compilation: If you're using AOT compilation to translate your templates, translation of the messages in .ts files will still be done at runtime using JIT compilation (that's why you need to reference TRANSLATIONS and TRANSLATIONS_FORMAT instead of just registering them in your build scripts).


app.module.ts

Add the following imports to your root Angular module:

import { TRANSLATIONS, TRANSLATIONS_FORMAT } from '@angular/core';
import { I18n } from '@ngx-translate/i18n-polyfill';

add the following constant, and specify the providers in your root module:

// add this after import + export statements
// you need to specify the location for your translations file
// this is the translations file that will be used for translations in .ts files

const translations = require(`raw-loader!../locale/messages.fr.xlf`);

@NgModule({ ....

  providers:
  [
    I18n,
    {provide: TRANSLATIONS, useValue: translations},
    {provide: TRANSLATIONS_FORMAT, useValue: 'xlf'},
    ...

*.ts

In the .ts file where you want to provide a translation, add this:

import { I18n } from '@ngx-translate/i18n-polyfill';

constructor(private i18n: I18n) {
    console.log(i18n("This is a test {{myVar}} !", {myVar: "^_^"}));
}

This demonstrates that you can even include interpolations in the messages that you want to translate.

You can use i18n definitions (i.e. using specifying the translation 'source' id, meaning, description) like this:

this.i18n({value: 'Some message', id: 'Some message id', meaning: 'Meaning of some message', description: 'Description of some message'})

You'll still need to extract the messages, and you can use the ngx-extractor tool to do this. See the readme on the polyfill page.

All of this is compatible with xliffmerge, which is a great tool for automatically merging any new translations you add, without overwriting existing translations. Xliffmerge can also automatically perform translations using Google translate (you'll need a Google translate API key). For this to work, I do the extraction and merging/translation in the following order, before I do the actual AOT build:

"extract-i18n-template-messages": "ng xi18n --outputPath=src/locale --i18n-format=xlf",
"extract-i18n-ts-messages": "ngx-extractor --input=\"src/**/*.ts\" --format=xlf --out-file=src/locale/messages.xlf",
"generate-new-translations": "xliffmerge --profile xliffmerge.json en fr es de zh"

The AOT build for a specific language version of the site looks like this:

"build:fr": "ng build --aot --output-path=dist/fr --base-href /fr/ --i18nFile=src/locale/messages.fr.xlf --i18nFormat=xlf --locale=fr",

Current status of this polyfill:

This is mainly written by Olivier Combe, a member of the Angular team responsible for i18n. At this stage this it's a 'speculative' polyfill for translating variables or strings in the .ts file. It's likely to be replaced by an API built into Angular which will be very similar, so upgrading later should be reasonably manageable. Here's the diclaimer from the Github page:

This library is a speculative polyfill, it means that it's supposed to replace an API that is coming in the future. If the API is different, a migration tool will be provided if it's possible and necessary.

There's been some discussion around support in forthcoming minor versions of Angular 6 for translations of variables/strings in code.

Here's a quote from Olivier Combe (from March this year), from the following discussion on Github:

https://github.com/angular/angular/issues/11405

The first PR for runtime i18n has been merged into master, along with a hello world demo app that we will use to test the features. It works at runtime, and support theoretically code translations, even if there is no service for it yet. For now it's very minimal support (static strings), we're working on adding new features (I'll make the extraction work next week, and then dynamic string with placeholders and variables). After that we'll do the service for code translations. As soon as a new feature is finished it gets merged into master, you won't have to wait for a new major.