Unleash the full power of angular-i18next

So first of all: “Why i18next?”

Let’s get into it…

Prerequisites

Getting started

import { APP_INITIALIZER, NgModule, LOCALE_ID } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { I18NEXT_SERVICE, I18NextModule, I18NextLoadResult, ITranslationService, defaultInterpolationFormat } from 'angular-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import { AppComponent } from './app.component';const i18nextOptions = {
debug: true,
fallbackLng: 'en',
resources: {
en: {
translation: {
"welcome": "Welcome to Your Angular App"
}
},
de: {
translation: {
"welcome": "Willkommen zu Deiner Vue.js App"
}
}
},
interpolation: {
format: I18NextModule.interpolationFormat(defaultInterpolationFormat)
}
};
export function appInit(i18next: ITranslationService) {
return () => {
let promise: Promise<I18NextLoadResult> = i18next
.use(LocizeApi)
.use<any>(LanguageDetector)
.init(i18nextOptions);
return promise;
};
}
export function localeIdFactory(i18next: ITranslationService) {
return i18next.language;
}
export const I18N_PROVIDERS = [
{
provide: APP_INITIALIZER,
useFactory: appInit,
deps: [I18NEXT_SERVICE],
multi: true
},
{
provide: LOCALE_ID,
deps: [I18NEXT_SERVICE],
useFactory: localeIdFactory
},
];
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
I18NextModule.forRoot()
],
providers: [
I18N_PROVIDERS
],
bootstrap: [AppComponent]
})
export class AppModule { }
<!-- Toolbar -->
<div class="toolbar" role="banner">
<span>{{ 'welcome' | i18next }}</span>
</div>
<div class="content" role="main"> <!-- Highlight Card -->
<div class="card highlight-card card-small">
<span>{{ 'welcome' | i18next }}</span>
</div>
</div>
<!-- Toolbar -->
<div class="toolbar" role="banner">
<span>{{ 'welcome' | i18next }}</span>
</div>
<div class="content" role="main"> <!-- Highlight Card -->
<div class="card highlight-card card-small">
<span>{{ 'welcome' | i18next }}</span>
</div>
<br />
<p>{{ 'descr' | i18next: { url: 'https://github.com/Romanchuk/angular-i18next' } }}</p>
</div>
const i18nextOptions = {
debug: true,
fallbackLng: 'en',
resources: {
en: {
translation: {
"welcome": "Welcome to Your Angular App",
"descr": "For a guide and recipes on how to configure / customize this project, check out {{-url}}."
}
},
de: {
translation: {
"welcome": "Willkommen zu Deiner Vue.js App",
"descr": "Eine Anleitung und Rezepte für das Konfigurieren / Anpassen dieses Projekts findest du in {{-url}}."
}
}
},
interpolation: {
format: I18NextModule.interpolationFormat(defaultInterpolationFormat)
}
};

Language Switcher

<!-- Footer -->
<footer>
<ng-template ngFor let-lang [ngForOf]="languages" let-i="index">
<span *ngIf="i !== 0">&nbsp;|&nbsp;</span>
<a *ngIf="language !== lang" href="javascript:void(0)" class="link lang-item {{lang}}" (click)="changeLanguage(lang)">{{ lang.toUpperCase() }}</a>
<span *ngIf="language === lang" class="current lang-item {{lang}}">{{ lang.toUpperCase() }}</span>
</ng-template>
</footer>
import { Component, Inject } from '@angular/core';
import { I18NEXT_SERVICE, ITranslationService } from 'angular-i18next';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.less']
})
export class AppComponent {
language: string = 'en';
languages: string[] = ['en', 'de'];
constructor(
@Inject(I18NEXT_SERVICE) private i18NextService: ITranslationService
)
{}
ngOnInit() {
this.i18NextService.events.initialized.subscribe((e) => {
if (e) {
this.updateState(this.i18NextService.language);
}
});
}
changeLanguage(lang: string){
if (lang !== this.i18NextService.language) {
this.i18NextService.changeLanguage(lang).then(x => {
this.updateState(lang);
document.location.reload();
});
}
}
private updateState(lang: string) {
this.language = lang;
}
}

Separate translations from code

How does this look like?

import { APP_INITIALIZER, NgModule, LOCALE_ID } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { I18NEXT_SERVICE, I18NextModule, I18NextLoadResult, ITranslationService, defaultInterpolationFormat } from 'angular-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import LocizeApi from 'i18next-locize-backend';
import { AppComponent } from './app.component';const i18nextOptions = {
debug: true,
fallbackLng: 'en',
backend: {
projectId: 'your-locize-project-id'
},
interpolation: {
format: I18NextModule.interpolationFormat(defaultInterpolationFormat)
}
};
export function appInit(i18next: ITranslationService) {
return () => {
let promise: Promise<I18NextLoadResult> = i18next
.use(LocizeApi)
.use<any>(LanguageDetector)
.init(i18nextOptions);
return promise;
};
}
export function localeIdFactory(i18next: ITranslationService) {
return i18next.language;
}
export const I18N_PROVIDERS = [
{
provide: APP_INITIALIZER,
useFactory: appInit,
deps: [I18NEXT_SERVICE],
multi: true
},
{
provide: LOCALE_ID,
deps: [I18NEXT_SERVICE],
useFactory: localeIdFactory
},
];
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
I18NextModule.forRoot()
],
providers: [
I18N_PROVIDERS
],
bootstrap: [AppComponent]
})
export class AppModule { }

save missing translations

const i18nextOptions = {
debug: true,
saveMissing: true, // do not use the saveMissing functionality in production: https://docs.locize.com/guides-tips-and-tricks/going-production
fallbackLng: 'en',
backend: {
projectId: 'my-locize-project-id',
apiKey: 'my-api-key' // used for handleMissing functionality, do not add your api-key in a production build
},
interpolation: {
format: I18NextModule.interpolationFormat(defaultInterpolationFormat)
}
};
<p>{{ 'cool' | i18next: { defaultValue: 'This is very cool!' } }}</p>

👀 but there’s more…

import { APP_INITIALIZER, NgModule, LOCALE_ID } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { I18NEXT_SERVICE, I18NextModule, I18NextLoadResult, ITranslationService, defaultInterpolationFormat } from 'angular-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import LocizeApi from 'i18next-locize-backend';
import LastUsed from 'locize-lastused';
import { locizePlugin } from 'locize';
import { AppComponent } from './app.component';const locizeOptions = {
projectId: 'my-locize-project-id',
apiKey: 'my-api-key' // used for handleMissing functionality, do not add your api-key in a production buildyour
};
const i18nextOptions = {
debug: true,
fallbackLng: 'en',
saveMissing: true, // do not use the saveMissing functionality in production: https://docs.locize.com/guides-tips-and-tricks/going-production
backend: locizeOptions,
locizeLastUsed: locizeOptions,
interpolation: {
format: I18NextModule.interpolationFormat(defaultInterpolationFormat)
}
};
export function appInit(i18next: ITranslationService) {
return () => {
let promise: Promise<I18NextLoadResult> = i18next
// locize-lastused
// sets a timestamp of last access on every translation segment on locize
// -> safely remove the ones not being touched for weeks/months
// https://github.com/locize/locize-lastused
// do not use the lastused functionality in production: https://docs.locize.com/guides-tips-and-tricks/going-production
.use(LastUsed)
// locize-editor
// InContext Editor of locize
.use(locizePlugin)
// i18next-locize-backend
// loads translations from your project, saves new keys to it (saveMissing: true)
// https://github.com/locize/i18next-locize-backend
.use(LocizeApi)
.use<any>(LanguageDetector)
.init(i18nextOptions);
return promise;
};
}
export function localeIdFactory(i18next: ITranslationService) {
return i18next.language;
}
export const I18N_PROVIDERS = [
{
provide: APP_INITIALIZER,
useFactory: appInit,
deps: [I18NEXT_SERVICE],
multi: true
},
{
provide: LOCALE_ID,
deps: [I18NEXT_SERVICE],
useFactory: localeIdFactory
},
];
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
I18NextModule.forRoot()
],
providers: [
I18N_PROVIDERS
],
bootstrap: [AppComponent]
})
export class AppModule { }

🎉🥳 Congratulations 🎊🎁

👍

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Adriano Raiano

Adriano Raiano

founder of locize.com; Software Architect, Bachelor in Computer Science #serverless #nodejs #cqrs #ddd always in search for #innovative and #disruptive stuff