Ionic 4 | Translate and Localize Your App With ngx-translate (Angular)

Written by on June 29, 2019

Ionic 4 | Translate and Localize Your App With ngx-translate (Angular)

I wrote the previous version of this article almost two years ago and I must admit not that much has changed. However, there is still enough content to validate the article update.

Just as in my previous article, this one will walk you through using Angular internationalization/translate library with Ionic 4. To do this we will use ngx-translate Angular library which is successor implementation of legacy Angular ng-translate module.

I will also showcase the most basic functionality. Hopefully, if I find the time I will also create a more advanced version of this topic.

Note: If this tutorial was helpful, you need further clarification, something is not working or you have a request for another Ionic post? Furthermore, leave me a comment below if you don't like something about this blog, if something is bugging you, don't like how I'm doing stuff here. Feel free to comment below, subscribe to my blog, mail me to dragan.gaic@gmail.com. Thanks and have a nice day!

Preparations

Before we can start, make sure your Ionic 4 work environment is up and ready.

We will need these:

  • Optional – Android or iOS Environment (you can always use browser)
  • NodeJS
  • Ionic 4
  • Cordova

If you do not have a preconfigured Ionic working environment follow the tutorial here: Ionic 4 | Installation Guide.

1. Update Ionic CLI

If you do not have Ionic and/or Cordova install them like this:

npm install -g ionic cordova

If you only need to update:

npm update -g ionic cordova

2. Create A New Project

ionic start IonicInternationalizationV2 blank
cd IonicInternationalizationV2 

You will find a working example at the end of this article, however, if you want to learn how this implementation works, keep reading further. Jump to the working example here.

Warning: As some of you don't have a prior Ionic CLI experience, from this point and on, every time I tell you to execute something, do that inside an example project folder.

3. Add Required Platform

For this example we only need a browser of your choice:

ionic cordova platform add browser

If you prefer the Android platform:

ionic cordova platform add android

Mac users can also add iOS platform:

ionic cordova platform add ios

4. Install ngx-translate library

We need these for our walk-through:

npm install @ngx-translate/core @ngx-translate/http-loader@latest rxjs --save

The @ngx-translate/core holds the basic implementation for the translation process, including some pipes.

The @ngx-translate/http-loader loads the json translation files from availably file system

Source Walkthrough

The provided example will use two different languages: English and Croatian. Each of these languages will have a separate language JSON file.

Let’s begin. Open src and assets folder. Now create the new folder and name it i18n. This name is predefined and you currently can’t configure it differently (the previous statement is no longer true, in the below example you will find how to deploy translations in any other folder). In this newly created folder, you will need to create a new file for each required language. I will create these two files as I already told you which languages we are going to use:

src/assets/i18n/en.json
                hr.json

If you don’t know your locale name you can find it like this:

console.log(navigator.language.split('-')[0]);

This is how en.json content looks like:

{
    "PAGE_TITLE" : "Translation tutorial",	
	"BUTTONS" : {
		"btn_eng" : "English",
		"btn_cro" : "Croatian"
	}
}

Next, we need to import the necessary modules in app.module.ts:

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

Don’t forget to include HttpClientModule and TranslateModule like this:

HttpClientModule,
TranslateModule.forRoot({
	loader: {
		provide: TranslateLoader,
		useFactory: HttpFactory,
		deps: [HttpClient]
	}
})],

or for a better idea:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';

import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';

import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';

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

@NgModule({
  declarations: [AppComponent],
  entryComponents: [],
  imports: [BrowserModule, 
            IonicModule.forRoot(), 
            AppRoutingModule, 
	        HttpClientModule,
	        TranslateModule.forRoot({
	            loader: {
	                provide: TranslateLoader,
	                useFactory: HttpFactory,
	                deps: [HttpClient]
	            }
	        })],
  providers: [
    StatusBar,
    SplashScreen,
    { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

// important for "ahead of time" compilation
export function HttpFactory(http: HttpClient) {
    return new TranslateHttpLoader(http);

    /* If you want to change the default translations folder do it like this */

    //return new TranslateHttpLoader(http, './assets/i18mnh/', '.json');
}

You will also notice that TranslateModule useFactory property requires a loader factory service. This factory is called TranslateHttpLoader and it is used to load translations from "/assets/i18n/[lang].json" file. You can copy it from my example, you don’t even need to change it:

export function HttpLoaderFactory(http: HttpClient) {
    return new TranslateHttpLoader(http);
}

But, if you like a clean code you can move it into a separate Class file. Find more information here.

Now let’s initialize ngx-translate. First, in the app.component.ts, import TranslateService and include it into constructor. Finally initialize it:

import {TranslateService} from '@ngx-translate/core';
  constructor(
    private platform: Platform,
    private splashScreen: SplashScreen,
    private statusBar: StatusBar,
    private translateService: TranslateService
  ) {
    this.initializeApp();
  }

  initializeApp() {
    this.platform.ready().then(() => {
      this.statusBar.styleDefault();
      this.splashScreen.hide();
      this.translateService.setDefaultLang('en');       
    });
  }

We have also initialized English as our default language.

At this point, the library is up and running, and both languages are available to our application.

One last thing, we also need to import TranslateModule into every page module. In our case it’s home.module.ts:

import { TranslateModule } from '@ngx-translate/core';

import { HomePage } from './home.page';

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    IonicModule,
    TranslateModule,
    RouterModule.forChild([
      {
        path: '',
        component: HomePage
      }
    ])
  ],
  declarations: [HomePage]
})
export class HomePageModule {}

To showcase how translation works, I have created a simple HomePage. It will have two buttons for language switching and some text where we can see these changes:

<ion-header>
	<ion-toolbar>
		<ion-title>{{ 'PAGE_TITLE' | translate }}</ion-title>
	</ion-toolbar>
</ion-header>

<ion-content>
	<ion-segment (ionChange)="segmentChanged($event)">
		<ion-segment-button checked value="en" color="primary">
			<ion-label>{{ 'BUTTONS.btn_eng' | translate }}</ion-label>
		</ion-segment-button>
		<ion-segment-button value="hr">
			<ion-label>{{ 'BUTTONS.btn_cro' | translate }}</ion-label>
		</ion-segment-button>
	</ion-segment>
</ion-content>

As you can see, the used syntax is equal to old ng/ng2-translate implementation.

For those of you who never worked with previous translate implementations, this line:

{{ 'BUTTONS.btn_eng' | translate }}

will pull BUTTONS.btn_eng content from the currently active JSON file. Let’s say en is our currently configured language. BUTTONS.btn_eng will translate to this line:

"BUTTONS" : {
	"btn_eng" : "English"
}

But what if we want to provide translations directly in our JavaScript code? You can use this syntax:

translateService.setTranslation('en', {
	IN_APP : 'Internal app translation'
});

translateService.setTranslation('hr', {
	IN_APP : 'Prijevod unutar aplikacije'
});
Continue to the next page

Categories

36 thoughts on “Ionic 4 | Translate and Localize Your App With ngx-translate (Angular)”

  1. Is there some changes with the alpha 51 ? While it works in my browser and ionic view (perfectly) but when built for android everything translation is blank. Does it do not find the directory ? In fact if I use the setTranslation instead of the useStatisFileLoader function it works also on android … Am I missing some file access rights settings in android ?

    • I’m sorry this was my mistake. I forgot to add a chapter dedicated to Cordova Whitelist plugin which is required for Android or iOS deployment.

      Look at a chapter: 4. INSTALL CORDOVA WHITELIST PLUGIN

      Unfortunately, you will need to download GitHub code again. First add Cordova Whitelist plugin then add required platform.

      • Is the install order important ? For I already have my android platform installed and now the the plugin has been installed and the index.html set as you specified, some http.get which wasn’t working until now on my android devices now are ok (So I guessed the install is correct) BUT for my translation files it still is not working … 🙁
        I added some tag in the config.xml but with no improvement whatsoever.

          • Well I don’t know for it seems that I followed every chapter as specified but it still is not working in my android device (no translation, everything is blank whereas I’m sure the plugin is working since my http get calls are now allowed). The only difference is that I could not execute the add android platform since it is already existing.

          • Hi, good article and example, but unfortunately i am getting the same error as Patrice.
            I followed the steps, everything is fine in browser with $ ionic serve, but $ ionic build android and then install .apk on my physical device (Nexus 4 with Android 5.1.1)

            $ ionic info
            Cordova CLI: 6.0.0-dev (cordova-lib@5.4.1)
            Gulp version: CLI version 3.9.0
            Gulp local:
            Ionic Version: 2.0.0-alpha.51
            Ionic CLI Version: 2.0.0-beta.17
            Ionic App Lib Version: 2.0.0-beta.8
            OS: Distributor ID: Ubuntu Description: Ubuntu 14.04.3 LTS
            Node Version: v5.4.1

            I am getting same error i a larger app i am building as well; everything works fine on browser, but nothing is diplayed in a .apk on a physical device.
            I am running Linux on a Chromebook, so i have (at least not for the moment, it is quirky) any possibility to run an android emulator.

          • Downgraded and done all steps again from fresh, with the same result. 🙁
            Cordova CLI: 5.4.1

          • I’ll try to set up some proper debugging tonight, will come back when find out what is going on here.

          • Got it working in my large app now, after debugging i found out that there was an extra slash added in the path to the json, producing a 404, so no translations available then.
            Before:
            var prefix = ‘assets/i18n/’;
            var suffix = ‘.json’;
            path: file:///android_asset/www/assets/i18n//sv.json = 404

            Now:
            var prefix = ‘./assets/i18n’;
            var suffix = ‘.json’;
            path: file:///android_asset/www/assets/i18n/sv.json = 200 OK

            I will try to step through your tutorial once more step-by-step and see if the same error occurs

          • How can I implement localization for plugin-command-buttons, like “ok” or “cancel” at ion-select element?

  2. Before I use in javascript side like this
    $translate.instant(‘hello’);
    But in ionic2 i can’t use anymore.

  3. what if i have 10 pages and i have to use translation each of 10 pages? In my main class App I inject TranslateService, then for each page i have to inject the TranslateService? What if i have to translate the same word in different pages, can i reuse the same code?

    Thank you for your article, it is great!

  4. I’m quite new to Ionic. Is that normal to put the “assets” folder inside of “www” instead of inside of the “app” folder?

  5. Is there a way to pass in dynamic values? Similar to PHP sprintf where you could have something like “You have %d messages” and it translates with the number of messages in the message.

  6. i think this is already outdated. ca you post an updated tutorial of ionic 2 internationalize-and-localize-your-app in javascript

  7. Thanks for nice post! How to avoid delaying first render and ensure at the same time that first renders will happen only after translations are ready?

  8. Thanks for the tutorial! But when the application closes and reopens the default language reappears. How to always keep the new language chosen?

Leave a Reply