How To Do Angular Internationalization + Angular Material (In 8 short steps)


So how do you add different translations to your Angular app?

In this article I'm going to show you how to build an Angular Material dashboard that supports multiple languages.

angular-material-dashboard-modified

Create the Angular app

ng new i8n-example

Add Angular Material

ng add @angular/material

Create the Angular Material Dashboard

ng generate @angular/material:navigation dashboard

Import the new dashboard component into our app component.

import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterOutlet } from '@angular/router';
import { DashboardComponent } from './dashboard/dashboard.component';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [CommonModule, RouterOutlet, DashboardComponent],
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'i8n-example';
}

Edit the app.component.html file to include the dashboard.

<app-dashboard></app-dashboard>

Now when we use the Angular CLI to run the app we'll see something like this.

angular-material-dashboard

Now we're ready to add the content to our dashboard. In this case it will be a simple heading that we will later dynamically translate to English and Spanish.

Preparing the dashboard

We will add a greeting header to the dashboard.component.html file.

<mat-sidenav-container class="sidenav-container">
  <mat-sidenav #drawer class="sidenav" fixedInViewport
      [attr.role]="(isHandset$ | async) ? 'dialog' : 'navigation'"
      [mode]="(isHandset$ | async) ? 'over' : 'side'"
      [opened]="(isHandset$ | async) === false">
    <mat-toolbar>Menu</mat-toolbar>
    <mat-nav-list>
      <a mat-list-item>English</a>
      <a mat-list-item>French</a>
      <a mat-list-item>Spanish</a>
    </mat-nav-list>
  </mat-sidenav>
  <mat-sidenav-content>
    <mat-toolbar color="primary">
      @if (isHandset$ | async) {
        <button
          type="button"
          aria-label="Toggle sidenav"
          mat-icon-button
          (click)="drawer.toggle()">
          <mat-icon aria-label="Side nav toggle icon">menu</mat-icon>
        </button>
      }
      <span>i8n-example</span>
    </mat-toolbar>
    <h1>Hello Joe 👋</h1>
  </mat-sidenav-content>
</mat-sidenav-container>

And our CSS code.

.sidenav-container {
  height: 100%;
}

.sidenav {
  width: 200px;
}

.sidenav .mat-toolbar {
  background: inherit;
}

.mat-toolbar.mat-primary {
  position: sticky;
  top: 0;
  z-index: 1;
}
h1 {
  margin-top: 2.2rem;
  margin-left: 2.2rem;
}

And the result.

angular-material-dashboard-modified

Now that we've got our dashboard set up, let's add the internationalize pieces.

Install the localize package

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

Creating the translation files

Now, we'll create two different translation files in the assets folder.

The first file will be assets/i18n/en.json with this content. This will have the English translation.

{
    "greeting": "Hello"
}

The second file will be assets/i18n/es.json with this content. This will have the Spanish translation.

{
    "greeting": "Hola"
}

Configuring the localize module

Now it's time to import the translation module.

Here's how we'll load it in the app.config.ts file.

import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';

import { routes } from './app.routes';
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';

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

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

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes), 
    provideAnimationsAsync(),
    provideHttpClient(),
    TranslateModule.forRoot({
      defaultLanguage: 'en',
      loader: {
        provide: TranslateLoader,
        useFactory: HttpLoaderFactory,
        deps: [HttpClient]
      }
    }).providers!
  ],
};

And now we're ready to start translating.

Dynamically translating greeting

This will done inside of the dashboard component.

We will be doing three things to the dashboard.component.ts file.

  • Importing the TranslateModule in the imports array.
  • Injecting the TranslateService in the constructor.
  • Adding a function to dynamically set the language.

Here's the code.

import { Component, inject } from '@angular/core';
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
import { AsyncPipe } from '@angular/common';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatButtonModule } from '@angular/material/button';
import { MatSidenavModule } from '@angular/material/sidenav';
import { MatListModule } from '@angular/material/list';
import { MatIconModule } from '@angular/material/icon';
import { Observable } from 'rxjs';
import { map, shareReplay } from 'rxjs/operators';
import { TranslateModule, TranslateService } from '@ngx-translate/core';

@Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html',
  styleUrl: './dashboard.component.css',
  standalone: true,
  imports: [
    MatToolbarModule,
    MatButtonModule,
    MatSidenavModule,
    MatListModule,
    MatIconModule,
    AsyncPipe,
    TranslateModule
  ]
})
export class DashboardComponent {

  constructor(private translateService: TranslateService) { }

  setLanguage(code: string) {
    this.translateService.use(code);
  }
}

Now, we'll change our mat-list-items to use the setLanguage function.

<mat-nav-list>
      <a mat-list-item (click)="setLanguage('en')">English</a>
      <a mat-list-item (click)="setLanguage('es')">Spanish</a>
</mat-nav-list>

And last of all, we'll use the translate pipe to dynamically translate the greeting.

<h1>{{ 'greeting' | translate }} Joe 👋</h1>

And you're done!

signature