Tutorial

How To Use ngx-translate with Angular

Angular

Introduction

At some point, your web application may require serving a multilingual user base. Internationalization, or i18n for short, is the process by which you make your app usable for those with a different native language.

While Angular has some built-in i18n functionality, ngx-translate is a third-party package that offers some functionality that might be better suited for your use case.

In this article, you will use ngx-translate in an Angular application.

Prerequisites

To complete this tutorial, you will need:

This tutorial was verified with Node v16.4.0, npm v7.19.0, @angular/core v12.1.0, @ngx-translate/core v13.0.0, and @ngx-translate/http-loader v6.0.0.

Setting Up the Project

Create a brand new Angular application and add some dependencies.

Open your terminal and use @angular/cli to create a new project:

  • ng new angular-ngx-translate-example --skip-tests

Then navigate to the newly created project directory:

  • cd angular-ngx-translate-example

Next, run the following command to add the package to your application:

  • npm install @ngx-translate/core@13.0.0

Now import the TranslateModule in your AppModule:

src/app/app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { TranslateModule } from '@ngx-translate/core';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    TranslateModule.forRoot()
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

This will provide access to the core of the translate service, pipe, and directives.

However, unless you plan on adding each and every translation yourself manually via code, you will probably want to add a little bit of configuration at this stage in order to make loading your translations a little easier.

Using TraslateHttpLoader

Probably the most common way to load translations is to include your translation files as assets and load them via the TranslateHttpLoader, which is available in a separate npm package.

  • npm install @ngx-translate/http-loader@6.0.0

Now import the TranslateHttpLoader in your AppModule:

src/app/app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule, HttpClient } from '@angular/common/http';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';

import { AppComponent } from './app.component';

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

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

You are free to create your own loader. You will need to implement the TranslateLoader interface and provide it in your module like above.

Using Translation Files

Creating the translation loader in this way expects you to have a file in your project under an /assets/i18n/ folder, called {lang}.json, where {lang} is the language of the file you are using for translations. For English, this file may be en.json, for example.

You can change the default path and file extension by providing extra parameters to the new TranslateHttpLoader() constructor.

The translation file is a JSON object of key-value pairs, where the key describes the text that is translated, and the value is the actual text in the language specified by the file.

src/assets/i18n/en.json
{
  "welcomeMessage": "Thanks for joining, {{ firstName }}! It's great to have you!",
  "login": {
    "username": "Enter your user name",
    "password": "Password here"
  }
}

The value may also be another object, which allows you to group your translations however you would like.

In the text of your translation value, you can also include double curly braces around a variable name, which will later allow you to interpolate strings dynamically into your translations.

Accessing Translations

Before you can access these translations in your application, you have to initialize some properties in the TranslateService.

Probably the best place to do this is in your bootstrapped AppComponent.

src/app/app.component.ts
import { Component } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  constructor(translate: TranslateService) {
    translate.addLangs(['en', 'klingon']);
    translate.setDefaultLang('en');
    translate.use('en');
  }
}

First, translate.addLangs([]) tells the service which languages are available to use for translations.

The method translate.setDefaultLang('en') allows you to specify a fallback set of translations to use in case there are missing translations for the current language.

translate.use('en') tells the service which is the current language to use for translations.

The parameter for all of these is the language you want to pull translations from - these should match the names of the JSON files that define the translations for those languages.

With that setup, you have three ways to access the translations. Which one you use at any given time will be up to your needs and preferences.

Using TranslateService

Using the service, there are two methods to get your translations.

The first, and recommended, method is to use:

get(key: string|Array<string>, interpolateParams?: Object)`

This returns an Observable, and as such, is asynchronous, which guarantees that the translation file will be loaded before using the value. This Observable then completes as soon as the value is retrieved.

The second method is to use:

instant(key: string|Array<string>, interpolateParams?: Object)`

This is synchronous. If the translation file isn’t finished loading at the time you use this method, you won’t get a translation at all.

Remember, we told the service to use en as the current lang, so all translation results will come from en.json initially.

src/app/app.component.ts
import { Component } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  user!: { firstName: string; lastName: string; };
  welcome!: string;
  usernameLabel!: string;
  passwordLabel!: string;

  constructor(translate: TranslateService) {
    translate.addLangs(['en', 'klingon']);
    translate.setDefaultLang('en');
    translate.use('en');
  }

  ngOnInit() {
    // hardcoded example
    this.user = { firstName: 'Sammy', lastName: 'Shark' };

    // synchronous. Also interpolate the 'firstName' parameter with a value.
    this.welcome = this.translate.instant('welcomeMessage', { firstName: this.user.firstName });

    // asynchronous - gets translations then completes.
    this.translate.get(['login.username', 'login.password'])
      .subscribe(translations => {
        this.usernameLabel = translations['login.username'];
        this.passwordLabel = translations['login.password'];
      });
  }
}

You can implement your own method in your application to switch between languages - whether through a select box, URL route, or some other method, call the use(lang: string) method on the TranslateService to set the current language.

Using TranslatePipe

You can use the translate pipe much like you’d use any other pipe in Angular. The input into the pipe is the key of the translation you need. The optional parameter is an object which defines any interpolation strings that the translation is expecting.

In the example below, the component has a user object, with a property of firstName:

src/app/app.component.html
<p>{{ 'welcomeMessage' | translate: user }}</p>

This code will produce a message of: "Thanks for joining, Sammy! It's great to have you!".

This matches the interpolation that is expected by the value of welcomeMessage.

src/app/app.component.html
<input type="password" placeholder="{{ 'login.password' | translate }}">

This code will produce an input with a placeholder of: "Password here".

Using TranslateDirective

You can also place a directive on any HTML element to get translations.

There are a couple of different ways to do this.

src/app/app.component.html
<label translate='login.username'></label>

This code will produce a label of: "Enter your user name".

You can also set the key of the translation as the content of the element.

src/app/app.component.html
<p translate [translateParams]="{ firstName: user.firstName }">welcomeMessage</p>

This code will produce a message of: "Thanks for joining, Sammy! It's great to have you!".

Conclusion

In this article, you used ngx-translate in an Angular application.

Continue your learning by reading about the built-in i18n support in Angular.

Creative Commons License