Tips

How to create a multilingual NativeScript app?

For an app project I needed a solution to switch from Dutch to English in real-time for our non-Dutch customers.

In my NativeScript Proof of Concept I built my own plain JavaScript solution with Jed. Although it worked, it wasn’t an ideal and pragmatic solution.

After the POC I decided to build the NativeScript app with Angular (2+) and started to look for existing internationalization (i18n) libraries for Angular. The best solution out there is ng2-translate, a project by Olivier Combe.

Getting it up-and-running in Angular was very easy, but getting it to work in NativeScript cost me a lot of blood, sweat and especially tears. Fortunately there is a awesome NativeScript community out there and Nathan Walker helped me out. In retrospect it takes only a few steps to incorporate ng2-translate.

You can follow the steps below or clone the sample project NSNL_Multilingual from Github.

1. Create a new NativeScript project with Angular

With the following commands we create a new project and add the Android and iOS platforms.


tns create projectname --ng
cd projectname
tns platform add android
tns platform add ios

2. Install ng2-translate

ng2-translate is a npm package and can be installed with the following command.


npm install ng2-translate --save

3. Create language files

Create the folder i18n in the app directory and add the files nl.json and en.json.

nl.json


{
    "EXAMPLE": {
        "TITLE": "Hallo wereld!",
        "TEXT": "Dit is een zin in het Nederlands.",
        "BACK": "Terug"
    }
}

en.json


{
    "EXAMPLE": {
    "TITLE": "Hello world!",
    "TEXT": "This is a sentence in English.",
    "BACK": "Back"
    }
}

4. Edit app.module.ts

We need to import the following modules.


import {NativeScriptHttpModule} from "nativescript-angular/http";
import {TranslateModule, TranslateLoader, TranslateStaticLoader} from "ng2-translate";
import {Http} from "@angular/http";

NativeScript uses Ahead-of-time compilation, so we need to export a function that returns the TranslateStaticLoader.


// for AoT compilation
export function translateLoaderFactory(http: Http) {
    return new TranslateStaticLoader(http, "/i18n", ".json");
};

And we also need to extend the @NgModule imports.


NativeScriptHttpModule,
TranslateModule.forRoot([{
    provide: TranslateLoader,
    deps: [Http],
    useFactory: (translateLoaderFactory)}])

5. Edit app.component.html

Replace the contents of app.component.html with the markup below.

This way we bind EXAMPLE.TITLE to the ActionBar label and the Label in the StackLayout. We also bind EXAMPLE.TEXT to the TextView.

And we have buttons available to switch between Dutch (Nederlands) and English. These buttons will fire the function changeLanguage when tapped.


<ActionBar [title]="'EXAMPLE.TITLE' | translate"></ActionBar>
<ScrollView>
    <StackLayout>
        <Label [text]="'EXAMPLE.TITLE' | translate"></Label>
        <TextView editable="false" [text]="'EXAMPLE.TEXT' | translate"></TextView>
        <Button text="Nederlands" (tap)="changeLanguage('nl')"></Button>
        <Button text="English" (tap)="changeLanguage('en')"></Button>
    </StackLayout>
</ScrollView>

6. Edit app.component.ts

We need to import the following modules.


import * as Platform from "platform";
import {TranslateService} from 'ng2-translate';

In the constructor we set the default language to Dutch.
After that we set the language based on the preferred language of the device. In case we don't have a JSON file in that language, ng2-translate will fallback to the default language.


constructor(private translate: TranslateService) {
    this.translate.setDefaultLang("nl");
    this.translate.use(Platform.device.language);
}

And we need a function to switch the language in real-time.


public changeLanguage(lang: string) {
    this.translate.use(lang);
}

And we're done! In only six steps you have built a multilingual NativeScript app!

Please don't forget to check out the sample project NSNL_Multilingual (see animation at the top of this article) on Github, which is a more extensive example including Angular routing.

Fellow developer Nic Raboy has a similar article about internationalization on his website. You might want to check that out too.