DEV Community

Cover image for Ngx-Translate: Internationalization (i18n) library for Angular
Ivan Simeonov
Ivan Simeonov

Posted on

Ngx-Translate: Internationalization (i18n) library for Angular

Internationalization in Angular using ngx-translate

Table of content

Introduction

Internationalization (i18n) is the process of adapting software to support multiple languages and cultures. In the world of Angular, ngx-translate is a popular library that helps developers add i18n support to their projects. By using ngx-translate, developers can easily translate static text in their applications, as well as dynamic content that is generated by user interactions. With its simple API and comprehensive documentation, ngx-translate makes it easy for developers to add internationalization to their Angular projects and ensure that their applications are accessible to users around the world. In this article, we will explore how to add ngx-translate to an Angular project and how to use it to create a multilingual user interface.

Optional steps

For the purposes of this tutorial, before integrating ngx-translate into an Angular project, we will have to first create one. Then we will add a styling library, such as Bootstrap and update the HTML and styles. At this stage we will ensure that the application is styled correctly and ready for the addition of i18n support. These steps are optional, but they will help to improve the overall look and feel of the application and make the integration of ngx-translate smoother and more successful.

Create Agnular project

I assume you already have the basic knowledge and you have your local environment ready to use AngularCLI. To create an empty Angular project using the AngularCLI, simply run the following command in the terminal window:

    ng new internation-demo
Enter fullscreen mode Exit fullscreen mode

After running the command above, the ng client will ask you if you want to add Angular routing and what stylesheet format would you like to use. In my case, I decided to add the routing and use SCSS. In this tutorial, we won't use the routing and the UI will be created with Bootstrap, so it doesn't matter, which one will you choose.

? Would you like to add Angular routing? Yes
? Which stylesheet format would you like to use? SCSS
Enter fullscreen mode Exit fullscreen mode

Add Bootstrap and flags icons libraries

In order to create the designs with ease, we will add Bootstrap and flag-icons libraries.

To add the libraries, run the following commands in terminal opened in the root of the project:

npm install bootstrap
npm i flag-icons
Enter fullscreen mode Exit fullscreen mode

Then in order use the styles, classes, etc., we will add them to the angular.json (there are other ways as well, f.e. importing them to the index.html, etc. but I personally prefer to add them to the angular.json).

Open angular.json file of your project and include:

"node_modules/bootstrap/dist/css/bootstrap.min.css"
Enter fullscreen mode Exit fullscreen mode

and

"node_modules/flag-icons/sass/flag-icons.scss",
Enter fullscreen mode Exit fullscreen mode

into the projects->architect->build->styles array
and

"node_modules/bootstrap/dist/js/bootstrap.js"
Enter fullscreen mode Exit fullscreen mode

into projects->architect->build->scripts array

Update the html and styles

Firstly, open the app.component.html and remove all the automatically generated code. Let's add our basic template that will be translated later on:

<nav class="navbar navbar-dark bg-dark fixed-top">
  <div class="container-fluid">
    <a class="navbar-brand">Internationalization</a>
    <div class="d-flex">
      <span class="fi fi-us me-2"></span>
      <span class="fi fi-de me-2"></span>
      <span class="fi fi-it me-2"></span>
      <span class="fi fi-es me-2"></span>
    </div>
  </div>
</nav>
<div class="container-fluid mt-3">
  <h1>What is ngx-translate</h1>
  <p>
    NGX-Translate is an internationalization library for Angular. It lets you define translations for your content in
    different languages and switch between them easily.
  </p>
  <p>
    It gives you access to a service, a directive and a pipe to handle any dynamic or static content.
  </p>
  <p>
    NGX-Translate is also extremely modular. It is written in a way that makes it really easy to replace any part with a
    custom implementation in case the existing one doesn't fit your needs.
  </p>
</div>
Enter fullscreen mode Exit fullscreen mode
Please consider the fact that the fixed navbar will overlay your other content, unless you add padding to the top of the body. Lets add the following code into the styles.scss file:
body {
    padding-top: 65px;
}
Enter fullscreen mode Exit fullscreen mode

After completion of the optional steps described above, we can start the app using ng serve -o command and we will see:

app-dashboard

Ngx Translate

Add ngx translate to the project

In order to use ngx-translate, first we have to install the npm module. Open a terminal in the root folder of your project and run the following command:

npm install @ngx-translate/core
Enter fullscreen mode Exit fullscreen mode

The @ngx-translate/core provides the translation's fundamental procedures, such as the TranslateService and the translate pipe.

There is no loader accessible by default. Although setTranslation may be used to manually add translations, it is preferable to utilize a loader. You may either develop your own loader or use an existing one. You may, for example, use the TranslateHttpLoader to load translations from files using HttpClient. To use it, simple install the http-loader package with the following command:

npm install @ngx-translate/http-loader
Enter fullscreen mode Exit fullscreen mode

The @ngx-translate/http-loader dynamically loads translation files from your web server.

Translation Module and HttpLoader Setup

Finally, in your Angular project, you may utilize ngx-translate. You must include TranslateModule.forRoot() in your application's base NgModule.

The forRoot static method is a convention that both offers and configures services. Make sure you only call this function in your application's root module, which is usually called AppModule. You can customize the TranslateModule using this method by supplying a loader, a parser, and/or a missing translations handler.

import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import {TranslateModule} from '@ngx-translate/core';

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

Enter fullscreen mode Exit fullscreen mode

Since we are going to use the TranslateHttpLoader, we should also do the following changes in order to load our translations from "/assets/i18n/[lang].json":

  • Add the HttpLoaderFactory function, that is required for AOT (ahead of time) compilation in your project.
  • Add HttpClientModule to the imports array in the AppModule
  • Configure the TranslateModule

HttpLoaderFactory method:

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

HttpClientModule & TranslateModule configuration

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

Enter fullscreen mode Exit fullscreen mode

Complete AppModule (app.module.ts) setup

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

import { AppRoutingModule } from './app-routing.module';
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,
    AppRoutingModule,
    HttpClientModule,
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: HttpLoaderFactory,
        deps: [HttpClient],
      },
    }),
  ],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}
Enter fullscreen mode Exit fullscreen mode

Translation Service Setup

Since we have configured the TranslationModule and the TranslateHttpLoader, we can move to the next step and initialize the TranslateService of our application. Let's jump into the AppComponent (app.component.ts) and initialize our service in the constructor.

AppComponent (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.scss'],
})
export class AppComponent {

  constructor(private translateService: TranslateService) {
    translateService.setDefaultLang('en');
    translateService.use('en');
  }
}

Enter fullscreen mode Exit fullscreen mode

As you can see from the code above, we have initialized the translation service. On the other hand, we have also added two other things:

  • translateService.setDefaultLang('en'); - Adds a fallback language when a translation isn't found in the current language
  • translate.use('en'); - Specifies the language to use, if it isn't available, the current loader will be used to get them

Now let's start the application using the ng serve -o command and you shall see the following (if you have followed the optional steps):

app-dashboard

The applications seems to work, but lets take a look at the browser console, where we have the following error:


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

Enter fullscreen mode Exit fullscreen mode

That is not unexpected. We have set the default and the fallback language to be en and the HttpLoader tries to load them from the server but we've not created that file yet. We will fix this in the next step.

Creation of JSON Translation files

Our demo application will support four languages: english, german, italian and spanish. Every single language will be stored in a separate JSON file, so let's create one for each. We will place those files in the /assets/i18n/ as shown below:

app-assets-structure

Now, since we've created the JSON files for every language, let's fill them with data following this best practices:

  • create detailed keys
  • use capital letters for the keys
  • don't use translation text as IDs
  • separate keys with multiple words with underscore (_)

en.json

{
  "NAVBAR": {
    "TITLE": "Internationalization"
  },
  "MAIN_CONTENT": {
    "TITLE": "What is ngx-translate?",
    "DESC_P1": "NGX-Translate is an internationalization library for Angular. It lets you define translations for your content in different languages and switch between them easily.",
    "DESC_P2": "It gives you access to a service, a directive and a pipe to handle any dynamic or static content.",
    "DESC_P3": "NGX-Translate is also extremely modular. It is written in a way that makes it really easy to replace any part with a custom implementation in case the existing one doesn't fit your needs."
  }
}

Enter fullscreen mode Exit fullscreen mode

de.json

{
  "NAVBAR": {
    "TITLE": "Internationalisierung"
  },
  "MAIN_CONTENT": {
    "TITLE": "Was ist ngx-translate?",
    "DESC_P1": "NGX-Translate ist eine Internationalisierungsbibliothek für Angular. Mit ihr können Sie Übersetzungen für Ihre Inhalte in verschiedenen Sprachen definieren und einfach zwischen ihnen wechseln.",
    "DESC_P2": "Es gibt Ihnen Zugriff auf einen Service, eine Direktive und eine Pipe, um jeden dynamischen oder statischen Inhalt zu verarbeiten.",
    "DESC_P3": "NGX-Translate ist auch extrem modular. Es ist so geschrieben, dass es sehr einfach ist, jeden Teil durch eine benutzerdefinierte Implementierung zu ersetzen, falls die vorhandene nicht Ihren Bedürfnissen entspricht."
  }
}


Enter fullscreen mode Exit fullscreen mode

it.json

{
  "NAVBAR": {
    "TITLE": "Internazionalizzazione"
  },
  "MAIN_CONTENT": {
    "TITLE": "Cos'è ngx-translate?",
    "DESC_P1": "NGX-Translate è una libreria di internazionalizzazione per Angular. Consente di definire traduzioni per i contenuti in diverse lingue e di passare facilmente da una all'altra",
    "DESC_P2": "Permette di accedere a un servizio, una direttiva e una pipe per gestire qualsiasi contenuto dinamico o statico",
    "DESC_P3": "NGX-Translate è anche estremamente modulare. È scritto in modo tale da rendere molto semplice la sostituzione di qualsiasi parte con un'implementazione personalizzata, nel caso in cui quella esistente non sia adatta alle proprie esigenze."
  }
}


Enter fullscreen mode Exit fullscreen mode

es.json

{
  "NAVBAR": {
    "TITLE": "Internacionalización"
  },
  "MAIN_CONTENT": {
    "TITLE": "¿Qué es ngx-translate?",
    "DESC_P1": "NGX-Translate es una librería de internacionalización para Angular. Te permite definir traducciones para tu contenido en diferentes idiomas y cambiar entre ellas fácilmente.",
    "DESC_P2": "Te da acceso a un servicio, una directiva y una tubería para manejar cualquier contenido dinámico o estático",
    "DESC_P3": "NGX-Translate es también extremadamente modular. Está escrito de tal forma que resulta realmente sencillo sustituir cualquier parte por una implementación personalizada en caso de que la existente no se ajuste a tus necesidades."
  }
}

Enter fullscreen mode Exit fullscreen mode

If you reload the application now and check the browser console, you will see that the error isn't there anymore.

Translations usage in templates and code

Now our translation JSON files are ready, so we can jump into the AppComponent (app.component.html) and start using them by replacing the static texts with references to the keys in the JSON files. In the ngx-translate are described multiple ways to add the translations but we will focus on the most popular and recommended one - using translation pipe.

Ex.: {{'key_id' | translate}}

AppComponent (app.component.ts) with translations added

<nav class="navbar navbar-dark bg-dark fixed-top">
  <div class="container-fluid">
    <a class="navbar-brand">{{ "NAVBAR.TITLE" | translate }}</a>
    <div class="d-flex">
      <span class="fi fi-us me-2"></span>
      <span class="fi fi-de me-2"></span>
      <span class="fi fi-it me-2"></span>
      <span class="fi fi-es me-2"></span>
    </div>
  </div>
</nav>
<div class="container-fluid mt-3">
  <h1>{{ "MAIN_CONTENT.TITLE" | translate }}</h1>
  <p>
    {{ "MAIN_CONTENT.DESC_P1" | translate }}
  </p>
  <p>
    {{ "MAIN_CONTENT.DESC_P2" | translate }}
  </p>
  <p>
    {{ "MAIN_CONTENT.DESC_P3" | translate }}
  </p>
</div>


Enter fullscreen mode Exit fullscreen mode

Bonus HTML Tags

We can use raw HTML tags within translations:

en/de/it/es.json

  ...
      "TITLE": "<a href='http://www.ngx-translate.com/'>What is ngx-translate?</a>"
  ...
Enter fullscreen mode Exit fullscreen mode

And to render them, we simply using the innerHTML attribute with pipe:

AppComponent (app.component.ts)

  ...
  <h1 [innerHtml]="'MAIN_CONTENT.TITLE' | translate"></h1>
  ...
Enter fullscreen mode Exit fullscreen mode

Runtime language changes

Now we have made all the configuration that we need, JSON files with the translations are created and the last thing that we are missing is to update the UI to switch between the language files we've created. To do so, let's do the following changes:

Add changeLanguage function into the AppComponent (app.component.ts):

  changeLanguage(language: string): void {
    this.translateService.use(language);
  }
Enter fullscreen mode Exit fullscreen mode

Bind country flags to click event in the template (app.component.html):

<span class="fi fi-us me-2" (click)="changeLanguage('en')"></span>
<span class="fi fi-de me-2" (click)="changeLanguage('de')"></span>
<span class="fi fi-it me-2" (click)="changeLanguage('it')"></span>
<span class="fi fi-es me-2" (click)="changeLanguage('es')"></span>
Enter fullscreen mode Exit fullscreen mode

Now reload the application and click on the different country flag to see the magic happening.

app-usage

Congrats!!!👏👏👏
You have successfully created an Angular application that supports four different languages!

Bonus Get Browser Language

If you want to apply the browser language, you can use the getBrowserLang() function. Keep in mind that it is really important to preset the default language, so when the browser language isn't found in our /assets/i18n/ folder, the application will still have a fallback language.

AppComponent (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.scss'],
})
export class AppComponent {
  defaultLang = 'en';

  constructor(private translateService: TranslateService) {
    translateService.setDefaultLang(this.defaultLang);

    let browserLang = translateService.getBrowserLang();
    if (browserLang) {
      translateService.use(browserLang);
    }
  }

  changeLanguage(language: string): void {
    this.translateService.use(language);
  }
}
Enter fullscreen mode Exit fullscreen mode

Summary

In conclusion, ngx-translate is a valuable tool for Angular developers who want to add internationalization to their projects. Its ease of use, comprehensive documentation, and active development community make it a reliable and effective solution for adding i18n support. Whether you are building a large, complex application or a simple single-page app, ngx-translate can help you reach a global audience by making your application accessible in multiple languages. So, if you are looking for a way to add i18n support to your Angular project, consider giving ngx-translate a try.

Contact Me

Top comments (0)