How to translate your Angular app with ngx-translate

2017-12-13 Andreas Löw

What you are going to learn in this tutorial

Here's a small outline of the tutorial:

How to set up ngx-translate

Create a simple demo project

For this tutorial you'll start with a simple demo application. I assume that you already have basic knowledge of Angular and AngularCLI is already installed on your system. You can of course skip this step and use your own project.

ng new translation-demo
cd translation-demo
ng serve

The demo project should now be available in your web browser under the following url: http://localhost:4200.

How to add ngx-translate your Angular application

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

The @ngx-translate/core contains the core routines for the translation: The TranslateService and some pipes.

The @ngx-translate/http-loader loads the translation files from your webserver.

Now you have to init the translation TranslateModule in your app.module.ts:

import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import {AppComponent} from './app.component';

// import ngx-translate and the http loader
import {TranslateModule, TranslateLoader} from '@ngx-translate/core';
import {TranslateHttpLoader} from '@ngx-translate/http-loader';
import {HttpClient, HttpClientModule} from '@angular/common/http';

    declarations: [
    imports: [
            loader: {
                provide: TranslateLoader,
                useFactory: HttpLoaderFactory,
                deps: [HttpClient]
    providers: [],
    bootstrap: [AppComponent]
export class AppModule {

// required for AOT compilation
export function HttpLoaderFactory(http: HttpClient) {
    return new TranslateHttpLoader(http);

The HttpLoaderFactory is required for AOT (ahead of time) compilation in your project.

Now switch to app.component.ts:

import {Component} from '@angular/core';
import {TranslateService} from '@ngx-translate/core';

    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
export class AppComponent {
    constructor(private translate: TranslateService) {

First, you have to inject TranslateService in the constructor.

The next step is to set the default language of your application using translate.setDefaultLang('en'). In a real app you can of course load language from the user's settings.

Reloading the app now shows an error in the browser console:

Failed to load resource: the server responded with a status of 404 (Not Found) http://localhost:4200/assets/i18n/en.json

This is because of the http loader which now tries to load the default language (en) from the server.

How to translate your application

The JSON translation file

Each language is stored in a separate .json file. Let's create the JSON file for the English translation: assets/i18n/en.json.

ngx-translate can read 2 JSON formats:

  "demo.title": "Translation demo",
  "demo.text": "This is a simple demonstration app for ngx-translate"


    "demo": {
        "title": "Translation demo",
        "text": "This is a simple demonstration app for ngx-translate"

This is just a matter of personal taste. The second one (so called namespaced-json format) is more structured and gives a better overview over the translations. It's the format I prefer. It's not important which one you choose — it's easy to convert one into the other later. Please use the second format for this tutorial.

Using translations

title and text are identifiers ngx-translate uses to find the translation strings. Now edit the app.component.html

You have two choices when it comes to adding translations:

Both options lead to the same result — it's just a matter of personal tast which one you want to use.

    <!-- translation: translation pipe -->
    <h1>{{ 'demo.title' | translate }}</h1>

    <!-- translation: directive -->
    <p [translate]="'demo.text'"></p>

Translations with parameters

ngx-translate also supports parameters in translations. They are passed as an object, the keys can be used in the translation strings.

<!-- translation: translation pipe -->
<p>{{ 'demo.greeting' | translate:{'name':'Andreas'} }}</p>

<!-- translation: directive -->
<p [translate]="'demo.greeting'" [translateParams]="{name: 'Andreas'}"></p>

And the extended translations file:

  "demo": {
    "greeting": "Hello {{name}}!"


Sometimes it's not enough to simply add a value to your translations. There are cases where parts or event the whole sentence has to change.

Think about the following situation: You want to display the number of images a user has uploaded.

Or you want to display a dynamic value:

The ngx-translate-messageformat-compiler is what you need now! It parses messages using the ICU syntax.

I've added the plugin to the demo project and found that it was not working at the moment (2017-12-14). The author of the plugin and ngx-translate are both aware of this and are working on a fix. I'll update this tutorial as soon as the fix is available.

Switching languages at runtime

To switch language you'll first have to add a new JSON file for that language. Let's create a German translation for the demo: assets/i18n/de.json

    "demo": {
        "title": "Übersetzungs-Demo",
        "text": "Dies ist eine einfache Applikation um die Funktionen von ngx-transalte zu demonstrieren.",
        "greeting": "Hallo {{name}}!"

Reloading the app will not show any differences — this is because you've set the default language to en in app.component.ts.

Make the following changes to the app.component.html to add a simple language switcher:

<button (click)="useLanguage('en')">en</button>
<button (click)="useLanguage('de')">de</button>

Add the following method to the app.component.ts

useLanguage(language: string) {

Update JSON files with ngx-translate-extract

Keeping the JSON files and your app in sync might become a challenge for more complex applications.

The good thing: Kim Biesbjerg created a tool called ngx-translate-extract. It scans your Angular app for the use of translations and adds new translations to your JSON files.

Start by adding it to your project:

npm install @biesbjerg/ngx-translate-extract --save-dev

You can add the following lines to your package.json to make using the tool more convenient:

"scripts": {
    "extract-translations": "ngx-translate-extract --input ./src --output ./src/assets/i18n/*.json --clean --sort --format namespaced-json --marker _"

Let's take a look at the parameters:

--input ./src
Sets the source directory in which to look for translations. The default is to scan all html and ts files. You can use an additional --patterns parameter to specify other file extensions.
--output ./src/assets/i18n/*.json
This specifies which files to update. The example here updates all existing language files in your ./src/assets/i18n folder that end with json. To add new languages simply add a new (empty) file to the translation folder. You can also list individual files if you prefer being more precise about what to update.
This option removes all translations that are not found in the source files. Usually it's a good idea to enable this to keep files consistent.
Sorts the JSON files.
--format namespaced-json
Creates the JSON files with the nested object structure as you used in this tutorial.
--marker _
ngx-translate-extract can search your TypeScript files for strings to translate. You have to surround the strings with a marker function e.g. _('app.title'). See below.

A simple command now updates your JSON files:

npm run extract-translations

Using translatable strings in your TypeScript files

Sometimes you have to add translatable strings to your TypeScript code. ngx-translate-extract needs a way to distinguish between these strings and all the other strings in your application.

This is where the marker function comes into play. The function itself does nothing — it only passes the string as a result.

import { _ } from '@biesbjerg/ngx-translate-extract';

    var messageBoxContent = _('messagebox.warning.text');

You can now use the pipe or directive to display the translated string:

<div>{{ messageBoxContent | translate }}</div>

Issues with Angular CLI

It seems that using the marker function in the ngx-translate-extract bundle currently does not work with AnguarCLI. ng serve is reporting the following error:

…/@biesbjerg/ngx-translate-extract/dist/cli/cli.d.ts (1,1): Cannot find type definition file for 'yargs'.

The best workaround for this is to add your own marker function in a separate translation-marker.ts file:

export function _(str: string) {
    return str;

And import it using

import { _ } from './translation-marker';

Conflicting marker function

In some cases using _() as a marker function might lead to conflicts with other modules. The solution is to create your own function — e.g. TRANSLATE()

export function TRANSLATE(str: string) {
    return str;

Also update your extract-translations command in package.json with --match TRANSLATE.

Editing JSON files with BabelEdit

Things are easy as long as you are only working with a single translation file. But as soon as you add a second language it becomes quite hard work to maintain both files. Not to speak of 5 or more languages.

To get started with BabelEdit download it from here:

The editor is currently in beta phase and you can use it for free.

Start BabelEdit after the installation. To get starteddrag & drop your assets/i18n-folder onto the main window.

BabelEdit now asks you for the languages contained in the files — making guesses from the file name:

Importing translations from JSON files

This is why we've created BabelEdit. It's a translation editor that can open multiple JSON files at once to work on them at the same time. Editing both translations from our example looks like this:

Using BabelEdit to translate an Angular application using ngx-translate

The left side contains a tree view with your translation ids, the right side the translations. The Approved checkbox allows you to mark translations as final. This additional information is stored in a BabelEdit project file (extension .babel).

The editor automatically reloads the files after they have been updated — e.g. from a new run of ngx-translate-extract.

BabelEdit currently used the flat JSON file format as default (because it's default in ngx-translate extract). If you use the namespaced-json format from our setup you have to change the format in the settings:

Choosing namespaced-json format for ngx-translate


With ngx-translate it's easy to create a multilingual version of your Angular app.

Use ngx-translate-extract to keep your translation files up-to-date.

Finally BabelEdit helps you to mange and edit your translations.

Did you like the tutorial? Please share!