A Complete Guide To Angular Multilingual Application (2024)

Hossein Mousavi

·

Follow

--

Initialize and implement an Angular i18n Application. A guide to how to implement multilingual applications with Angular using Transloco! Including lazy loading translation.

A Complete Guide To Angular Multilingual Application (3)
  • Overview of Internationalization (i18n) and Localization
  • Initializing an Angular application and installing the packages
  • Project Configurations
  • Translation Inside The Template
  • Translation Inside The TypeScript
  • Change The Active Language
  • Lazy Loading The Translation Files

You can skip to the implemented example code in this GitHub repository and check out a working demo here.

Over the past decades, there have been tons of applications with users all around the globe. Hence the necessity of implementing products and services for users based on their language and culture has been sensed. We call this process internationalization (i18n “I” — eighteen letters -“N”). On the other hand, localization is adapting a specific product to a unique local market. Angular localization provides us with a handful of features:

  • Extract text for translation into different languages
  • Format data for a specific locale

We can use Angular’s internationalization for:

  • Use built-in pipes to display dates, numbers, percentages, and currencies in a local format.
  • Mark text in component templates for translation.
  • Mark plural forms of expressions for translation.
  • Mark alternate text for translation.
A Complete Guide To Angular Multilingual Application (4)

First, we need an Angular application! I presume you have installed the Angular CLI on your machine. For initializing an Angular Application using Angular CLI, we could type:

ng new <PROJECT_NAME>

In this Medium story, we are not going into the implementation details of the Angular application. You can find this GitHub repo to see the project’s full implementation. Start your Angular application using the ng serve command. Now that we have our Angular project running let’s get to the implementation details of i18n.

We are going to use Transloco for simplicity. First, we need to install the necessary packages.

ng add @ngneat/transloco

After executing the following command, you need to answer a couple of questions, like whether or not you are using Angular Universal in your project and what languages you will support. After answering them, you may find new files in your project.

You need to type ISO 639–1 code of your language. For example, if you want your application to include English, German, Spanish, And Persian, you need to type: en, de, es, fa.

A Complete Guide To Angular Multilingual Application (5)

You can find the config file for transloco on transloco-root.module.ts file. You can change the languages you support, your application’s default language, and whether or not you want to change your language on runtime. You can find the list of all options here.

import { HttpClient } from '@angular/common/http';
import {
TRANSLOCO_LOADER,
Translation,
TranslocoLoader,
TRANSLOCO_CONFIG,
translocoConfig,
TranslocoModule,
} from '@ngneat/transloco';
import { Injectable, isDevMode, NgModule } from '@angular/core';

@Injectable({ providedIn: 'root' })
export class TranslocoHttpLoader implements TranslocoLoader {
constructor(private http: HttpClient) {}

getTranslation(lang: string) {
return this.http.get<Translation>(`/assets/i18n/${lang}.json`);
}
}

@NgModule({
exports: [TranslocoModule],
providers: [
{
provide: TRANSLOCO_CONFIG,
useValue: translocoConfig({
availableLangs: ['en', 'de', 'fa'],
defaultLang: 'en',
reRenderOnLangChange: true,
prodMode: !isDevMode(),
}),
},
{ provide: TRANSLOCO_LOADER, useClass: TranslocoHttpLoader },
],
})
export class TranslocoRootModule {}

Now you need to import TranslocoRootModule in your root module, which is most likely called app.module.ts .

Key takeaway: In order to work with Angular’s modules, and services, we need to import the coressponded module into our module, for this purpose, we need to import TranslocoRootModule once in our app.module.ts and for all of our feature modules, we need to import TranslocoModule .

A Complete Guide To Angular Multilingual Application (6)

After executing the ng add @ngneat/transloco command, you find a directory called i18n in your assets directory with all the languages you have specified. These are the main language files. You may use it on your home page or header. But you can also create a unique directory for each module and then lazy load them into your module. We will cover the lazy loading in a second. First, let’s start working with Transloco.

Using Structural Directive

You can use *transloco directives in your template. But you need to either import translocoModule for feature modules or for the main page, translocoRootModule. Imagine we want to translate our title. We need to include the translated text inside the JSON files in the i18n directory.

The en.json should look like the following:

{
"title": "Hello World!"
}

And for translating into another language (let’s say German), the de.json should be something like this:

{
"title": "Hallo Welt!"
}

Now in our template, by using the directive, we can demonstrate the selected language’s value like below:

<h1 *transloco="let t"> {{ t("title") }} </h1>

But let’s say we may have a complicated JSON structure with nested key properties like the below:

// JSON does not support comments like this. 
// These comments are only for demonstrating.

// en.json
{
"title": "Hello World!",
"form": {
"firstName": "First Name",
"lastName": "Last Name"
}
}

// de.json
{
"title": "Hallo Welt!",
"form": {
"firstName": "Vorname",
"lastName": "Nachname"
}
}

Now we have two options. Either use nested items in the t function, or let the directive where look for the value:

<!-- option 1 -->
<h1 *transloco="let t"> {{ t("form.firstName") }} </h1>

<!-- option 2-->
<h1 *transloco="let t; read:'form'"> {{ t("firstName") }} </h1>

Option two is more readable.

Using Pipe

Another approach is by using the pipes like the below:

<h1>{{ 'title' | transloco }}</h1>

After injecting the TranslocoService Into our component, we can safely use it like the below:

export class AppComponent {
constructor(private readonly translocoService: TranslocoService) {}

ngOnInit() {
this.translocoService.translate('title');
this.translocoService.translate('form.firstName')
}
}

There are other translation APIs that you can find them all here. But remember that for these APIs to work correctly, you must ensure that the translation files have been loaded at runtime.

Once the user clicks on the button responsible for changing the application’s language, we must change the selected language of the application. For that, first, let’s create a proper component. You can find the fully implemented component here.

import { Component } from '@angular/core';
import { TranslocoService } from '@ngneat/transloco';

@Component({
selector: 'app-language-selector',
template: `
<div>
<button
*ngFor="let language of languagesList; index as i"
(click)="changeLanguage(language.code)"
>
<img [src]="language.imgUrl" [alt]="language.name" />
<span> {{ language.shorthand }} </span>
</button>
</div>
`,
})
export class LanguageSelectorComponent {
constructor(private translocoService: TranslocoService) {}
public languagesList:
Array<Record<'imgUrl' | 'code' | 'name' | 'shorthand', string>> = [
{
imgUrl: '/assets/images/English.png',
code: 'en',
name: 'English',
shorthand: 'ENG',
},
{
imgUrl: '/assets/images/Deutsch.png',
code: 'de',
name: 'German',
shorthand: 'GER',
},
{
imgUrl: '/assets/images/Persian.png',
code: 'fa',
name: 'Persian',
shorthand: 'PER',
},
];
public changeLanguage(languageCode: string): void {
this.translocoService.setActiveLang(languageCode);
languageCode === 'fa'
? (document.body.style.direction = 'rtl')
: (document.body.style.direction = 'ltr');
}
}

As you can see, we’ve implemented three buttons for changing the application’s language to English, German, and Persian. Once the user clicks on the button, using we will call the setActiveLang method on translocoService with the selected language’s code.
Please consider that languages like Persian and Arabic are written from right to left. So do not forget to change your application’s direction from rtl to ltr have changed the direction of the body.

A Complete Guide To Angular Multilingual Application (7)

Loading all the translation files at once on your application’s initialization is not a good idea, especially if you have tons of modules. Besides increasing your application's load time, working on a single translation file for your whole application is challenging. Fortunately, we can lazy load the translation files into our modules.
Let’s say we have two modules called pageOne and pageTwo. For each module, we will create a directory inside our i18n directory. Do not forget to fill the directories with the same number of JSON files for each language. Now we only need to indicate the scope for each module. There are a couple of ways to do so.

<!-- pageOne module -->
<h1 *transloco="let t; scope:'pageOne'"> {{ t('title') }} </h1>
<!-- Pay attention to the scope above -->

Every other details, such as the read method, are the same. If you want to lazy load translation inside your TypeScript, you can achieve this goal easily.

First, in your module, where you have imported the translocoModule you need to specify the desired scope

const routes: Routes = [
{
path: '',
component: PageOneComponent
}
];

@NgModule({
declarations: [PageOneComponent],
providers: [{ provide: TRANSLOCO_SCOPE, useValue: 'pageOne' }],
imports: [RouterModule.forChild(routes), TranslocoModule]
})
export class PageOneModule {}

Now you can access the current scope in your TypeScript file like below:

export class AppComponent {
constructor(
private translocoService: TranslocoService,
@Inject(TRANSLOCO_SCOPE) private scope
) {}

ngOnInit() {
this.translocoService.selectTranslate('title', params, this.scope)
.subscribe(console.log);
}
}

By injecting TRANSLOCO_SCOPE into your component, you can use the current scope of the module.

A Complete Guide To Angular Multilingual Application (8)

You can see a fully implemented Demo on:

https://angular-multi-lingual.hmousavi.dev

You can also check out its GitHub repository:

https://github.com/hossein13m/angular-multi-lingual

Please do not hesitate to share your thoughts and ideas with me. You can reach me on Twitter or find another way by visiting my portfolio.

Read more from me:

Multiple Interceptors in AngularOne of the amazing features that Angular provides is the interceptors, but what does an Interceptor do, and can we…medium.com
Husky 6 Lint (prettier + eslint) and commitlint for JavaScript ProjectsProgramming is a teamwork job so we must assure that our codebase is clean and usable for everyone in the team with the…medium.com
Angular forms (Reactive Form) including Angular Material and Custom ValidatorForms are major parts of every Angular project and in this article, we want to implement a Reactive Angular form with a…medium.com
Take a good look at filter, map and reduce in JavaScriptIn JavaScript we have These three methods as parts of Array.prototype methods, but what are the differences between…hossein13m.medium.com
A Complete Guide To Angular Multilingual Application (2024)

References

Top Articles
Latest Posts
Article information

Author: Arline Emard IV

Last Updated:

Views: 5547

Rating: 4.1 / 5 (72 voted)

Reviews: 95% of readers found this page helpful

Author information

Name: Arline Emard IV

Birthday: 1996-07-10

Address: 8912 Hintz Shore, West Louie, AZ 69363-0747

Phone: +13454700762376

Job: Administration Technician

Hobby: Paintball, Horseback riding, Cycling, Running, Macrame, Playing musical instruments, Soapmaking

Introduction: My name is Arline Emard IV, I am a cheerful, gorgeous, colorful, joyous, excited, super, inquisitive person who loves writing and wants to share my knowledge and understanding with you.