DEV Community

Cover image for Translate in Ionic 5 using apps and PWA
Abhijeet Rathore for Enappd

Posted on • Originally published at enappd.com

Translate in Ionic 5 using apps and PWA


In this post you’ll learn how to translate text in Ionic 5 apps and PWA. You will also learn how to get device specific language and convert your app’s text to the same language / locale.

Ionic has a variety of app types nowadays (Angular/React/Vue , Cordova/Capacitor). This post will explore the Ionic apps made in Angular Cordova, but the same process can apply in Angular Capacitor apps as well.

Translation in Apps — how is it done ?

Multi-language translation, OR internationalization 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 ! But with growing apps users, every app is now focusing on translating to local languages.

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 5 apps. There are 3 major steps in the translation process in an app —

  1. 1. Translation Language — Detect the language you want to translate into. This can either be done automatically by detecting phone or browser’s language (Globalization), OR, can be done with user actions (say, by using a dropdown).For our use case, we will detect device’s language using both Cordova Globalization plugin and Browser’s Internationalization API.
  2. 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. 3. Translate — After the above two steps, you finally translate your app’s text to the intended language. We will use ngx-translate library for translating our texts as we are talking about only Angular Ionic apps in this post

Structure of the post

So the development outline of this blog will be

  1. 1. Create a starter Ionic 5 tab app
  2. 2. Prepare multiple language JSON files in assets
  3. 3. Implement ngx-translate library to detect and translate AND Implement Cordova Globalization plugin or browser Internationalization API to detect device language
  4. 4. Test translations on browser
  5. 5. The Directive Gotcha
  6. 6. Setup stand alone translations
  7. 7. Test translations on Android / iOS

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

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

Step 1— Create a basic Ionic Angular app

First you need to make sure you have the latest Ionic CLI. This will ensure you are using everything latest. Ensure latest Ionic CLI installation using

$ npm install -g ionic@latest

Here’s my environment for this blogpost

Ionic:
Ionic CLI : 6.10.1
Ionic Framework : @ionic/angular 5.3.1
@angular-devkit/build-angular : 0.901.12
@angular-devkit/schematics : 9.1.12
@angular/cli : 9.1.12
@ionic/angular-toolkit : 2.3.0
Cordova:
Cordova CLI : 9.0.0 (cordova-lib@9.0.1)
System:
Android SDK Tools : 26.1.1
NodeJS : v12.14.0
npm : 6.13.4
OS : macOS Catalina
Xcode : Xcode 11.5 Build version 11E608c

Creating a basic Ionic-Angular app. Start a basic tabs starter using

$ ionic start ionicTranslate tabs --type=angular --cordova

The --type=angular told the CLI to create an Angular app, and --cordova tells the CLI to integrate Cordova in the app.

Run the app in browser using

$ ionic serve

You won’t see much in the homepage created in the starter. I have modified pages ( tab1 and tab2) to align it to our translation functionality.

My tab pages look like this


Tab UI for translation

HTML and SCSS file code for the above UI, if you want to just get started

Step 2 — Prepare multiple language JSON files in assets

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}}"}
}

Note, the value and name_value are kind of variable/constants we can pass from our component. This can be used to

  • Replace the variable with a user input or a value depending on the situation OR
  • To give translations not supported by the library OR
  • Keep a word constant across translations

STEP 3: Implement ngx-translate library and Cordova Globalization plugin

Cordova globalization plugin is used to detect device’s default language/locale. Unfortunately, this plugin is deprecated, but it is still supported by Ionic. Hence, you can opt to use it. However, the latest way of detecting the language / locale of the browser is by using browsers’s default Internationalization API.

Install Cordova globalization Plugin using

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

Install ngx-translate library

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

// 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.

Note the versions of ngx-translate you should have as per your Angular version


Use appropriate version of ngx-translate based on your Angular version

Setup the translation library and http-loader

We need to define a function that loads the external JSON files to the app using http-loader. Add the following function to app.module.ts

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

  • On page load we check if we have default browser internationalization API by checking window.Intl . We then get default browser language using navigator.language . We also set a fall back on Cordova globalization plugin (deprecated) and set a default language if neither browser nor Cordova plugin works.
  • Then we use this._translate.use(this.language) to tell the translation service which language to translate to. If the app has just loaded, it should default to your browser’s default language OR en (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— Test translations on browser

Run the app on browser using ionic serve and test the translations using the dropdown. Here’s a GIF to show the functionality on browser

Translate in Ionic 5 using ngx-translate

Translate in Ionic 5 using ngx-translate

Notice that the text loads in English by default in my browser. You can change your browser language from browser settings and check if the initial text loads in your default language. For chrome, the settings can be found here

Change your browser language to load app text in default language

Change your browser language to load app text in default language

And now my text loads default in French …. Bonjour !!

Step 5 — 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 5 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. 😎 😎 😎

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 6— Setup stand alone translations

The process of setting up separate language file in assets for each language is the standard way of translation in Angular. But sometimes it becomes a little cumbersome, especially when you don’t have that much data to translate.

In case you want to quickly translate in the component itself, so that there is no spill over on other components, you can declare the variables in the components itself instead of reading them from the JSON files from assets

Let’s do these changes in tab2, so it doesn’t affect the global translations in tab1

HTML and SCSS

Similar to tab1.page.html , just remove the usage of variable data from the HTML. You can keep the styling same

tab2.page.ts

Stays pretty much same as tab1.page.ts . Just add the following in the constructor

_translate.setTranslation('en', {
 "TITLE": "Bye sir",
 "TITLE_2": "Bye {{value}}",
 "description": "Thanks for translating this text"
});
_translate.setTranslation('fr', {
 "TITLE": "Au revoir Monsieur",
 "TITLE_2": "Au revoir  {{value}}",
 "description": "Merci d'avoir traduit ce texte"
});
_translate.setTranslation('es', {
 "TITLE": "Adiós señor",
 "TITLE_2": "Adiós {{value}}",
 "description": "Gracias por traducir este texto"
});

Here, you are defining the translations locally in your component itself. Also, to let angular know that these are standalone translations, you use isolate:true in your tab2.module.ts

....
TranslateModule.forChild({
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient]
},
isolate: true
}),
....

Now run the app in browser and test translations. Your translations will be picked from the local component itself

Translation in Ionic 5 apps using component level translations

Translation in Ionic 5 apps using component level translations

Notice, the directive method and variable also work well with the local definitions.

Step 7 — Test translations in iOS/Android

To build the app on android, run the following commands one after another

$ ionic cordova platform add android
$ ionic cordova run android

The final command will run the app on either default emulator, or an android device attached to your system. Here’s the translation running on my android device

Ionic 5 Angular app — Translation and Globalization

Ionic 5 Angular app — Translation and Globalization

Interesting fact: In device, the language id may be different from browser. For me
- Device default language comes out to be en-US
- Browser’s default language comes out to be en

Hence, you need to be careful to detect all variations of a language. Accordingly, you’ll need to have JSON file named accordingly.

Conclusion

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

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.


Next Steps

If you liked this blog, you will also find the following Ionic blogs interesting and helpful. Feel free to ask any questions in the comment section


Ionic React Full App with Capacitor

If you need a base to start your next Ionic 5 React Capacitor app, you can make your next awesome app using Ionic 5 React Full App in Capacitor

Ionic 5 React Full App in Capacitor from Enappd

Ionic 5 React Full App in Capacitor from Enappd

Ionic Capacitor Full App (Angular)

If you need a base to start your next Angular Capacitor app, you can make your next awesome app using Capacitor Full App

Capacitor Full App with huge number of layouts and features

Capacitor Full App with huge number of layouts and features

Ionic Full App (Angular and Cordova)

If you need a base to start your next Ionic 5 app, you can make your next awesome app using Ionic 5 Full App

Ionic Full App with huge number of layouts and features

Ionic Full App in Cordova, with huge number of layouts and features

Top comments (0)