DEV Community

loading...
Cover image for How to build painless multi-language apps with Angular and ngx-translate

How to build painless multi-language apps with Angular and ngx-translate

Federico Navarrete
👨‍💻 Cloud Architect, Author & 🎤 Speaker always ready to Lead Digital Transformations 💡
Updated on ・3 min read

I'm sure if you're reading this post is because either you're curious or you understand the pain of supporting multiple languages in Angular.

I love Angular and it's my main JS Modern Framework, but there is something that drives me nuts its poor multi-lingual support. It's extremely over-complicated to my taste.

I have developed multiple websites and over 11 apps for Windows and Android and I cannot understand how the creators couldn't be inspired by Google's most important OS, Android.

In Android, you only need a couple of XMLs (en, es, etc.), minor adjustments in the UI XMls, or code something in Java/Kotlin and magically, you have an app that supports multiple languages.

After several attempts, I found ngx-translate, which leveraged my work significantly. So, how to use it?

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

Next, configure your app.module.ts

1. Enable the translation service:

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

2. Configure the loader:

a. Root domain (www.mydomain.com):

export function translateHttpLoaderFactory(http: HttpClient) {
  return new TranslateHttpLoader(http);
}
Enter fullscreen mode Exit fullscreen mode

b. Sub-domains (myself.github.io/myapp):

export function translateHttpLoaderFactory(http: HttpClient) {
  return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}
Enter fullscreen mode Exit fullscreen mode

In this option, you are going to configure the location of your JSON files.

3. Configure your constructor (my version auto-detects the browser language and set it by default):

availableLng = ['en', 'es'];

//start the translation service
constructor(private translateService: TranslateService) {
    //defines the default language
    const tmpLng = 'en';

    //gets the default browser language
    const currentLng = window.navigator.language.substring(0,2);

    if (this.availableLng.includes(currentLng))
    tmpLng = currentLng;

    translateService.setDefaultLang(tmpLng);
}
Enter fullscreen mode Exit fullscreen mode

4. Add to your imports:

    HttpClientModule,
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: translateHttpLoaderFactory,
        deps: [HttpClient]
      }
    })
Enter fullscreen mode Exit fullscreen mode

Your final app.module.ts might look like this one:

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

/* IMPORTANT:
   This only works if you are setting your app in your main domain: www.mydomain.com
*/
export function translateHttpLoaderFactory(http: HttpClient) {
  return new TranslateHttpLoader(http);
}

/*
   For sub-domains like myself.github.io/myapp
   You need to use this code or a variation with the location of your assets:
*/

/*
export function translateHttpLoaderFactory(http: HttpClient) {
  return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}
*/

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

export class AppModule {
  //define available languages
  availableLng = ['en', 'es'];

  //start the translation service
  constructor(private translateService: TranslateService) {
    //defines the default language
    const tmpLng = 'en';

    //gets the default browser language
    const currentLng = window.navigator.language.substring(0,2);

    if (this.availableLng.includes(currentLng))
  tmpLng = currentLng;

    translateService.setDefaultLang(tmpLng);
  }
}
Enter fullscreen mode Exit fullscreen mode

After, create a new folder in assets called i18. Inside of it, you are going to create the language assets like en.json:

{
  "Title": "Translation demo",
  "WelcomeMessage": "Welcome to the international demo application"
}
Enter fullscreen mode Exit fullscreen mode

And es.json:

{
  "Title": "Demo de traducción",
  "WelcomeMessage": "Bienvenido a la aplicación de demostración internacional"
}
Enter fullscreen mode Exit fullscreen mode

Now, inside the HTML part of your components, you can call it like this:

<h1 translate>Title</h1>
Enter fullscreen mode Exit fullscreen mode

Where translate indicates the tag that is going to be translated and Title the JSON key.

Can this be extended beyond HTML tags?

Definitely, what if you have a placeholder in an input?

You can use it like this:

<input placeholder="{{'Title' | translate}}" />
Enter fullscreen mode Exit fullscreen mode

Or how do you use it from the TypeScript file?

First, enable it from the component constructor:

constructor(private translateService: TranslateService) { }
Enter fullscreen mode Exit fullscreen mode

Next, activate the default language in ngOnInit():

ngOnInit() {
    this.translations = this.translateService.store.translations[`${this.translateService.defaultLang}`];
}
Enter fullscreen mode Exit fullscreen mode

Later, you can access it with a simple piece of code like this one:

console.log(this.translations.WelcomeMessage);
Enter fullscreen mode Exit fullscreen mode

The greatest benefit in my experience with ngx-translate is that it works and looks similar to common Apps development in Android or Windows.

This post has some inspiration from Yaser's blog:

https://yashints.dev/blog/2018/01/17/multi-language-angular-applications

Plus, if you want to see a full action app using this framework, you can check it here:

https://fanmixco.github.io/gravitynow-angular

Also, here is its repository:

https://github.com/FANMixco/gravitynow-angular

Follow me at:

LinkedIn
GitHub

Discussion (0)