Localization & Internationalization in Angular 6 CLI for enhancing multi-language functionality

Our Application is built on Angular 6 and we are looking to incorporate multilingual support.

Please advise on how we can enable localization and internationalization in Angular 6. This pertains specifically to the Angular 6 version.

Answer №1

For more information, please visit:

Guidelines for Translating Angular 6 Applications Using ngx-translate:

Here are the steps we will be taking:

  • Create a minimal Angular 6 project
  • Install and load ngx-translate
  • Initialize the TranslateService
  • Create .json translation files
  • Translate simple title and intro
  • Integrate language switcher
  • Translate sentences with variables

Utilizing Nested .json Objects

Create a Minimal Angular 6 Project:

To start, use @angular/cli to create a new project named "traduction" in the terminal:

ng new traduction --prefix tr
cd traduction
ng serve -o

Installing and Loading ngx-translate:

In your project folder "traduction", use npm in the terminal:

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

Note: Use the following versions for angular 6 and below:

"@ngx-translate/core": "^9.1.1" 
"@ngx-translate/http-loader": "^3.0.1"

For Angular 5, use the latest version 10 and above

Importing Necessary Modules into app.module.ts :

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

Add a function that returns a "TranslateHttpLoader" and export it as needed by AoT. This function loads translations using Http and .json:

export function HttpLoaderFactory(http: HttpClient) {
  return new TranslateHttpLoader(http);
}

OR

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

Next, import the modules into the @NgModule which tells Angular to load this Module into your AppModule:

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

Injecting the TranslateService:

In "app.component.ts", initialize the "TranslateService" by importing it:

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

Within the AppComponent Class, inject the service, define the default language, and add a function to switch languages:

constructor(private translate: TranslateService) {
    translate.setDefaultLang('en');
}

switchLanguage(language: string) {
    this.translate.use(language);
}

Creating .json Translation Files:

Create translation files inside the assets/i18n folder:

src/assets/i18n/en.json

{
    "Title": "Translation example",
    "Intro": "Hello I am Arthur, I am 42 years old."
}

src/assets/i18n/fr.json

{
    "Title": "Exemple de traduction",
    "Intro": "Bonjour je m'appelle Arthur, j'ai 42 ans."
}

These .json files will be loaded by the "TranslateHttpLoader" created in "app.module.ts".

Translating Simple Title and Intro:

In app.component.html, use the translate directive within the h1 tag to translate text. Also, use the TranslationPipe to translate labels with inline strings:

<h1 translate>Title</h1>

<div>
{{ 'Intro' | translate:user }}
</div>

Integrating Language Switcher:

Attach the language switcher function to buttons in app.component.ts and call the switchLanguage() function with the corresponding language key:

<button (click)="switchLanguage('en')">en</button>

<button (click)="switchLanguage('fr')">fr</button>

Translating Sentences with Variables:

To handle sentences containing variables, pass an object into the "translate" pipe and use its properties in the translation:

...
export class AppComponent {
  user = {
    name: 'Arthur',
    age: 42
};
...

Now you can use these properties in your translations:

src/assets/i18n/en.json

{
    "Title": "Translation example",
    "Intro": "Hello I am {{name}}, I am {{age}} years old."
}

src/assets/i18n/fr.json

{
    "Title": "Exemple de traduction",
    "Intro": "Bonjour je m'appelle {{name}}, j'ai {{age}} ans."
}

Using Nested .json Objects:

If you want more control over your translations, consider using nested .json objects to translate page blocks or components. Here's an example of how to structure the .json files:

{
    "Title": "Translation example",
    "Intro": "Hello I am {{name}}, I am {{age}} years old.",
    "Startpage": {
        "TranslationSections": "Hello World"
    },
     "Aboutpage": {
        "TranslationSections": "We are letsboot"
    }
}


{
    "Title": "Exemple de traduction",
    "Intro": "Bonjour je m'appelle {{name}}, j'ai {{age}} ans.",
    "Startpage": {
        "TranslationSections": "Bonjour Monde"
    },
    "Aboutpage": {
        "TranslationSections": "Nous sommes letsboot"
    }
}

Template Usage:

<h1 translate>Title</h1>

<div>
{{ 'Intro' | translate:user }}
</div>

<div>
{{ 'Startpage.TranslationSections' | translate }}
</div>

<div>
{{ 'Aboutpage.TranslationSections' | translate }}
</div>

<br/>

<button (click)="switchLanguage('en')">en</button>
<button (click)="switchLanguage('fr')">fr</button>

Answer №2

app.module.ts

export function customTranslateLoaderFactory(http: HttpClient) {
  return new CustomTranslateLoader(http);
}
TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: customTranslateLoaderFactory,
        deps: [HttpClient]
      }
    })

class LanguageHandler.ts

import { Injectable } from '@angular/core';
import { TranslateService, LangChangeEvent } from '@ngx-translate/core';
import { ReplaySubject } from 'rxjs';
import { take } from 'rxjs/operators';
@Injectable({ providedIn: 'root' })
export class LanguageHandler {
    language$ = new ReplaySubject<LangChangeEvent>(1);
    translate = this.translateService;

    constructor(private translateService: TranslateService) {}

    setInitialLanguage() {
      this.translateService.addLangs(['en', 'cn','vi']);
      console.log( 'Browser Lang', this.translate.getBrowserLang());
      const browserLang = (this.translate.getBrowserLang().includes('vi')) ? 'vi' : 'cn'  ;
      console.log("Setting language to " +browserLang);

      this.setLanguage(browserLang);
    }

    setLanguage(lang: string) {
      this.translateService.onLangChange.pipe(take(1)).subscribe(result => {
        this.language$.next(result);
      });
      this.translateService.use(lang);

    }
  }

home.component.html

<h1>Implementing multi-language support in Angular 7</
<p >{{'content' |translate}}</p>
<h4 translate>
  {{'message' |translate}}
</h4>
<button (click)="selectEN()">English</button>
<button (click)="selectCN()">Chinese</button>
<button (click)="selectVI()">Vietnamese</button>

Demo:

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

There was a parsing error due to encountering an unexpected reserved word 'interface' in the code, as flagged

I'm encountering an issue with my code when trying to utilize Props. The error message I'm receiving is "Parsing error: Unexpected reserved word 'interface'. (3:0)eslint". This project is being developed using next with TypeScript. Er ...

The Generic Function's Return Type in Typescript

The latest addition of ReturnType in TypeScript 2.8 is a highly valuable feature that enables you to capture the return type of a specific function. function foo(e: number): number { return e; } type fooReturn = ReturnType<typeof foo>; // numbe ...

Converting Simplified Chinese GB 2312 characters to UTF-8 encoding

Is there a way to convert text from multi-byte text strings, such as Simplified Chinese GB 2312, into UTF8 using C++? ...

Encountering a 404 error while attempting to "Fetch data" in a .NET Core SPA template application, specifically when utilizing a proxy

After creating an Angular project with the .NET core 2.2 and spa template, I made modifications to startup.cs in order to implement a proxy development server while serving angular. This allowed me to run my server and client code separately. I referred t ...

Navigating through a JSON dictionary in Svelte: A step-by-step guide

When working with Svelte, the #each construct allows for easy iteration over array-like objects. But what if you have a JSON dictionary object instead? Is there a way in Svelte to iterate over this type of object in order to populate a dropdown menu? The ...

getting requestParam of type date from angular using spring

Hello everyone, I am new to working with Angular and Spring. I am attempting to send a GET request with some date parameters, but I keep encountering an error. Here is the HTML code snippet: <div class="form-row"> <div c ...

Is there a way to close a window in JavaScript that was opened using Ionic Capacitor?

Currently, I am trying to open a window within my Ionic app by using the code snippet below: await Browser.open({url: environment.apiUrl + `/myurl`}); However, upon completion of a certain action by the user, I want to close that same window. Unfortunate ...

Activate the event when the radio button is changed

Is there a way to change the selected radio button in a radio group that is generated using a for loop? I am attempting to utilize the changeRadio function to select and trigger the change of the radio button based on a specific value. <mat-radio-group ...

In TypeScript, the 'as const' syntax results in a syntax error due to the missing semicolon

I incorporated the following code into my react project: export const animation = { WAVES: "waves", PULSE: "pulse", } as const; export type Animation = typeof animation[keyof typeof animation]; Upon running the project, I encounte ...

The child element is triggering an output event that is in turn activating a method within the parent

I am currently utilizing @Output in the child component to invoke a specific method in the parent component. However, I am encountering an issue where clicking on (click)="viewPromotionDetails('Learn more')" in the child component is al ...

Displaying errors from an API using Angular Material mat-error

I am currently working on a form that includes an email field. Upon saving the form, the onRegisterFormSubmit function is called. Within this function, I handle errors returned by the API - specifically setting errors in the email form control and retrie ...

Navigating to the main directory in Angular 2

I am currently diving into the world of Angular 2 and attempting to create my very first application. I am following a tutorial from Barbarian Meets Coding to guide me through the process. Following the steps outlined in the tutorial, I have set up my appl ...

Tips for organizing your Typescript code in Visual Studio Code: avoid breaking parameters onto a

Currently, I am working on an Angular project using Visual Studio Code and encountering an irritating issue with the format document settings for Typescript files. It keeps breaking parameters to a new line: Here is an example of the code before formattin ...

Unable to generate a file on Firebase platform

I've made updates to my firestore rules, and while the simulator is working correctly, I'm encountering an insufficient permissions error when creating a new document. Below are the firebase rules in question: match /users/{usersid} { a ...

When using Angular 5's ngModel, the user interface displays the updated value dynamically without requiring the

When filling out my form, I encounter an issue with a select element and a bind variable. If I make a change to the value and save it, everything works as expected. However, if I make a change in a modal window but then close the modal without saving the v ...

Loop through a collection of map instances in TypeScript

In my TypeScript code, I am making a call to an API method in a Java class that returns a list of maps. The TypeScript file includes the code snippet below. When attempting to retrieve data from dataBody, it displays as [Object Object]. I need assistance ...

Having trouble viewing the initial value in an AngularJS2 inputText field

I'm having trouble displaying the initial value in inputText. I'm unsure of what mistake I'm making, but the value should be showing up as expected. Kind regards, Alper <input type="text" value="1" [(ngModel)]="Input.VSAT_input1" name= ...

Upon completing the installation of the @angular/cli@latest node module, the ng file was unexpectedly missing

I'm currently working on Git Bash on my Windows 10 machine. The command I used was: npm install --save @angular/cli@latest Here is the result: + @angular/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="bad9d6d3fa8b899488 ...

Issues with Angular Material Form Fields Functioning Incorrectly

Recently, I came across a boilerplate template that helped me integrate an Angular Element component into a SharePoint Framework webpart. Following this template and the package.json provided below: "dependencies": { "@angular/animations": "5.2.11", ...

Concealing a column in ngx-datatable Ionic

I am just starting to work with NGX-datatable and I need to populate my data table in my Ionic app with data from Firebase. Here is the format of the JSON returned from Firebase: If I choose not to use the User_id as a column, how can I access the User_id ...