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.
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.
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.
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!