How to translate in Ionic 4 — Globalization, Internationalization and Localization



Type caption for image (optional)
Complete code of this blog is available at https://github.com/enappd/ionic4-i18n

Multi-language translation, OR internationalization-localization is a growing need for every app that wants to target international customers. Till date, majority of apps have been developed in English, no surprise ! In this blog post we will learn how to implement translation, OR technically — Internationalization + Localization in Ionic 4 apps.

First we need to understand the steps involved in the process. Translations, thanks to Google, look very easy, but they are a bit involved in case of apps and websites, in our case Ionic 4 apps. There are 3 major steps in the translation process in an app —

  1. Translation Language — Detect the language you want to translate into. This can either be done automatically by detecting phone or browser’s language, OR, can be done with user actions (say, by using a dropdown).
    For our use case, we will detect device’s language using Cordova Globalization plugin.
  2. Prepare Language Text — You need to have a pre-translated dictionary (or JSON file) which stores the translations of all your app’s text in the Translation language. There are several ways to do this, as we’ll see in following steps. This is mostly a manual process for smaller apps, but you can use online tools like this for quick translations, or like POEditor for more standardized workflow.
  3. Translate — After the above two steps, you actually translate your app’s text to the Translation language text. We will use ngx-translate library for translating our texts.

Development Pre-requisites

Following is my development environment info, just in case you want to match. Out of these having Ionic 4.x is essential. Node v10.x would be good to have as well.

Ionic:
ionic (Ionic CLI)             : 4.11.0 
Ionic Framework               : @ionic/angular 4.1.1
@angular-devkit/build-angular : 0.13.5
@angular-devkit/schematics    : 7.2.4
@angular/cli                  : 7.3.5
@ionic/angular-toolkit        : 1.4.0
Cordova:
cordova (Cordova CLI) : 8.0.0
Cordova Platforms     : ios 4.5.5
System:
ios-deploy : 1.9.2
ios-sim    : 5.0.13
NodeJS     : v10.0.0 (/usr/local/bin/node)
npm        : 5.6.0
OS         : macOS Mojave
Xcode      : Xcode 10.1 Build version 10B61

Also, for running the app on iOS device, you need to have correct version of Xcode. My current version is Xcode 10.1, when iOS is v12.x. For android device, you need the correct android SDK and libraries installed, along with a device (or simulator).

Outline

So the development outline of this blog will be

  1. Create a starter Ionic 4 tab app (I’ll tell later why I chose tab app)
  2. Prepare multiple language JSON files
  3. Implement ngx-translate library to detect and translate
  4. Implement a basic page layout to show translated text in browser
  5. Implement Cordova Globalization plugin to detect device language.
  6. Run the app on iOS simulator to translate by phone’s default language

We will translate text in 2 other languages — French and Spanish

Sounds pretty easy, right ? Well, let’s dive right into it.

That did not …. translate very well 😛

STEP 1 : Create Ionic 4 app

This section is mostly for beginners. Once you have Ionic 4 installed in your system, you can create a basic Tab app by running

ionic start yourAppName tabs
// Change to app folder
cd yourAppName
// Start the app in browser
ionic serve

This will give you the pretty app view in the browser. Cool, right?

Ionic serve on browser

Also get familiar with the Folder structure. src/app/tab1 andsrc/app/tab2 are of our interest for further development. These are the folders for Tab 1 and Tab 2 respectively.

STEP 2: Prepare language JSON files

We will create these JSON files in src/assets/i18n folder. The assets folder remains in the root even after a production build, so the path does not break. We will create three JSON files en.json (English), fr.json (French) and es.json (Spanish).

Folder structure for i18n files

en.json

{
"TITLE": "Hello sir",
"TITLE_2": "Hello {{value}}",
"description": "Ooohh .... did you just translate this text ?",
"data": {"name": "My name is {{name_value}}"}
}

fr.json

{
"TITLE"         : "Bonjour Monsieur",
"TITLE_2"       : "Bonjour {{value}}",
"description"   : "Ooohh .... vous venez de traduire ce texte?",
"data"          :{"name": "je m'appelle {{name_value}}"}
}

es.json

{
"TITLE": "Hola señor",
"TITLE_2": "Hola {{value}}",
"description": "Ooohh .... acabas de traducir este texto?",
"data": {"name": "Me llamo {{name_value}}"}
}

The {{value}} and {{name_value}} are kind of variable/constants we can pass from our component. This can be used to keep a word constant across translations OR to give translations not supported by the library.

STEP 3: Implement ngx-translate library

ngx-translate is the internationalization (i18n) library for Angular. Since Ionic 4 has Angular under the hood by default, we can use this library for app as well as progressive web apps.

Install library

// Install core library
npm install --save @ngx-translate/core
// Install http loader
npm install @ngx-translate/http-loader --save

http-loader is used for loading the translation files (JSONs in our case) via Angular’s HttpClient module.

Setup the library and http-loader

We need to define a function that loads the external JSON files to the app using http-loader. This function looks like this

export function HttpLoaderFactory(http: HttpClient) {
return new TranslateHttpLoader(http, "./assets/i18n/", ".json");
}

where we have provided the external path of our JSON files to the function.

We need to add the translation and http-loader modules in our root module (app.module.ts). This is how the file looks after setup.

Pay attention to TranslateModule.forRoot() This is used in case of a Tabbed application, or general non lazy-loaded module. For a tab child, however, we will have to use TranslateModule.forChild() . We will see later how this will affect our functionality.

Setup the translate library in child component

Let’s say, we want to implement the translation in Tab1. As mentioned previously, src/app/tab1 folder contains all the files for this page. We will import the translationService in tab1.page.ts file using

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

The completed tab1.page.ts file will look like this

Let’s break down the code to understand a bit more

  • ionViewDidEnter() runs when the page loads. We then get default browser language using this._translate.getBrowserLang() (for browsers) and set a default language if no browser
  • Then we use this._translate.use(this.language) to tell the translation service which language to translate to (in our case English)
  • Important: Usethis._translate.get('TITLE').subscribe() function from translateService to asynchronously fetch translations. Here,
    - get() is the function to fetch translations.
    - TITLE is the key to search for in the JSON files. If the data is in a nested JSON, then we use the dot notation to fetch e.g. data.name
    - subscribe is used for asynchronous fetching (no need to use timeouts)
  • changeLanguage is called from user action. This function will use the previous two steps to translate to the intended language.

STEP 4: Basic page layout to show translated text

We will create a very basic layout to enable language selection and show translated text in the app.
Language selection can be done with a simple ion-select which acts like a selection list. We will show different types of translated text in ion-card layout. Final layout will look like the following

Text translated in all three languages. Select option at the top of the page

The layout file tab1.page.html will have the following layout

Run all these changes on your ionic serve and Voila ! You got yourself some translations 🎉 🎉 🎉 🎉

Text translation on browser

The Directive GOTCHA 😎

If you have followed the above steps exactly, you might not get the exact result as shown in the above GIF.

You will realize that the translation works in places where you have used

this._translate.get('TITLE').subscribe((res: string) => {           
this.title = res;
});
this._translate.get('description').subscribe((res: string) => {           
this.description = res;
});

to get the translation, and shown it in the HTML using the local variable like this

<h1>{{ title }}</h1>
<p>{{ description }}</p>

BUT, the translation does not work in places where you have used a directive like either of the following

<h1 translate>TITLE</h1>
<p [translate]="'description'"></p>

This is because in our Ionic 4 tab app, the tab pages are lazy-loaded. In lazy-loaded modules, you need to import the translation module in child modules as well for everything to work correctly.

Let’s go to our tab1.module.ts file, and import the translation and http-loader modules similar to our root module. But this time, we will use TranslateModule.forChild . The complete module file looks like the following

Now, if you run the app again, the directive translations will also work fine. 😎 😎 😎

Translating in tab app — like a boss

directive method is preferred for bigger apps with lots of code, since this method results in smaller code size and no need of local variables.

STEP 5: Implement Cordova Globalization plugin

To perform the translation using device’s default language, we need to detect the device’s default language first. This can be done using globalization plugin. Install the plugin using

ionic cordova plugin add cordova-plugin-globalization
npm install @ionic-native/globalization

Import the plugin in your component using

import { Globalization } from '@ionic-native/globalization/ngx';
constructor(private globalization: Globalization) { }

Now you can call a simple function on your page start, which will detect the device’s default language

getDeviceLanguage() {
this.globalization.getPreferredLanguage().then(res => {
// Run other functions after getting device default lang
this._initTranslate()
})
.catch(e => console.log(e));
}

STEP 6: Run the app on simulator

To run the app on simulator, first add iOS platform

ionic cordova platform add ios

Then prepare the app for iOS build

ionic cordova prepare ios

After this, you can either build the app directly using Xcode, or use Ionic CLI to run the app in default simulator. I prefer Xcode, as it can handle all provisioning related errors better. To run from Ionic CLI directly, use

ionic cordova run ios --target="iPhone-6s"

This is what you will see in Safari Console if you are running on device or simulator. I changed the default language on the simulator to french

Getting device default language — iOS simulator

Interesting fact: Since Ionic apps are based on browser itself, detecting browser’s default language is enough. As you see in the above example,
- device default language comes out to be fr-US 
- browser’s default language comes out to be fr

So, for our case, detecting browser language itself is enough. But, it is good to be able to detect device’s default language in case it differs from browser’s language.

Conclusion

In this post we learnt how to detect device / browser language, create multiple language files, and implement translation using different methods.

The only limitation of using the ngx-translate library is that you will need to define your language texts on each page of your application beforehand .These will be stored as country code titled JSON files (i.e. en.json, jp.json, it.json etc) within the src/assets/i18n/ directory. You can’t dynamically generate the language translation on the fly using this library so if you require that type of functionality you’ll need to look into using the Google Translate API or something similar.

This blog was originally published on Enappd.



NEED FREE IONIC 4 STARTERS?

You can also find free Ionic 4 starters on our website enappd.com


🐦 Follow Enappd on Twitter FacebookLinkedin🕸

It’s great having you here, please click 👏 button and share 👭 this article to help others find it! Feel free to leave a comment below.


Title
Subtitle
Kicker