Internationalization - i18n
The @genesislcap/foundation-i18n
package provides a collection of services and utilities based on the i18next framework to enable your application to handle more than one language.
Key features
- Easy integration: Quick set-up with modern JavaScript frameworks and libraries.
- Dynamic language switching: The user can select to change language on the fly without reloading the application.
- Module federation support: Share and load translations dynamically across different micro front-ends or modules.
- Dependency injection: Integrate i18n services into your components using dependency injection.
Importing and configuring i18n
Once you have installed foundation-i18n, you can import the necessary modules from @genesislcap/foundation-i18n
and configure your language settings.
Here is an example that provides headings in both English and Portuguese:
import { defaultI18nextConfig, I18nextConfig } from '@genesislcap/foundation-i18n';
// Tip: Extend or modify the defaultI18nextConfig as needed.
Registration.instance<I18nextConfig>(I18nextConfig, {
...defaultI18nextConfig,
lng: 'pt', // en is the default language but you can change it here or by tweaking the defaultI18nextConfig
resources: {
en: {
translation: {
Home: 'Home',
Admin: 'Admin',
Reporting: 'Reporting',
Notifications: 'Notifications',
['Features Lab']: 'Features Lab',
},
},
pt: {
translation: {
Home: 'Início',
Admin: 'Administração',
Reporting: 'Relatórios',
Notifications: 'Notificações',
['Features Lab']: 'Laboratório de Funcionalidades',
},
},
},
});
This could live in your application’s entry point, such as main.ts
or a similar file.
Storing translation information in JSON
Alternatively, you can use a JSON file to store your translations and load them dynamically. For example:
{
"en": {
"translation": {
"Home": "Home",
"Admin": "Admin",
"Reporting": "Reporting",
"Notifications": "Notifications",
"Features Lab": "Features Lab"
}
},
"pt": {
"translation": {
"Home": "Início",
"Admin": "Administração",
"Reporting": "Relatórios",
"Notifications": "Notificações",
"Features Lab": "Laboratório de Funcionalidades"
}
}
}
Then, import the JSON file and use it in your configuration:
import { defaultI18nextConfig, I18nextConfig } from '@genesislcap/foundation-i18n';
import translations from './translations.json';
Registration.instance<I18nextConfig>(I18nextConfig, {
...defaultI18nextConfig,
lng: 'en',
resources: translations,
});
addResources
You can add resources dynamically and whenever necessary.
This is useful when:
- you have a large number of translations
- you need to from a different source
- you want to load translations at a different time from the initial set-up
This will overwrite any resources you have set previously.
import { I18next } from '@genesislcap/foundation-i18n';
import translations from './translations.json';
export class MyExampleClass {
@I18next i18next!: I18next;
addResources() {
this.i18next.addResources(translations);
}
}
Usage
foundation-i18n
enables your application to change languages dynamically, without needing to reload:
import { I18next } from '@genesislcap/foundation-i18n';
import { customElement, FASTElement, html } from '@microsoft/fast-element';
import translations from './translations.json';
@customElement({
name: 'my-example-component',
template: html`
<zero-button @click=${() => addResources()}>Add Translation Resources</zero-button>
<zero-button @click=${() => switchLanguage()}>Switch between PT and EN</zero-button>
<zero-button @click=${() => translateWords()}>Translate i18n Resource Words</zero-button>
`,
})
export class MyExampleComponent extends FASTElement {
@I18next i18next!: I18next;
addResources() {
this.i18next.addResources(translations);
}
switchLanguage() {
if (this.i18next.language === 'pt') {
this.i18next.changeLanguage('en');
} else {
this.i18next.changeLanguage('pt');
}
}
translateWords() {
console.log(this.i18next.t('Home')); // if pt, it will log Início, if en, it will log Home
console.log(this.i18next.t('Admin')); // if pt, it will log Administração, if en, it will log Admin
console.log(this.i18next.t('Reporting')); // if pt, it will log Relatórios, if en, it will log Reporting
console.log(this.i18next.t('Notifications')); // if pt, it will log Notificações, if en, it will log Notifications
console.log(this.i18next.t('Features Lab')); // if pt, it will log Laboratório de Funcionalidades, if en, it will log Features Lab
}
}
Integrating with other libraries
Angular example
To integrate @genesislcap/foundation-i18n
with an Angular application, you can configure i18next
in a service and use it throughout your components.
i18n.service.ts
import { Injectable } from '@angular/core';
import { defaultI18nextConfig, I18next } from '@genesislcap/foundation-i18n';
import translations from './translations.json';
import { DI } from '@microsoft/fast-element';
@Injectable({
providedIn: 'root',
})
export class I18nService {
private container = DI.getOrCreateDOMContainer();
private i18n = this.container.get(I18nService);
constructor() {
this.i18n.init({
...defaultI18nextConfig,
lng: 'en',
resources: translations,
});
}
switchLanguage() {
const newLanguage = this.i18n.language === 'en' ? 'pt' : 'en';
this.i18n.changeLanguage(newLanguage);
}
translate(key: string): string {
return this.i18n.t(key);
}
}
app.component.ts
import { Component } from '@angular/core';
import { I18nService } from './i18n.service';
@Component({
selector: 'app-root',
template: `
<button (click)="switchLanguage()">Switch Language</button>
<p>{{ translate('Home') }}</p>
<p>{{ translate('Admin') }}</p>
<p>{{ translate('Reporting') }}</p>
`,
})
export class AppComponent {
constructor(private i18nService: I18nService) {}
switchLanguage() {
this.i18nService.switchLanguage();
}
translate(key: string): string {
return this.i18nService.translate(key);
}
}
React example
To integrate @genesislcap/foundation-i18n
with a React application, create a separate service for handling i18next
just as you would create other services.
i18nService.js
import { defaultI18nextConfig, I18next } from '@genesislcap/foundation-i18n';
import { DI } from '@microsoft/fast-foundation';
import translations from './translations.json';
class I18nService {
private container = DI.getOrCreateDOMContainer();
private i18n: Connect = this.container.get(I18next);
constructor() {
this.i18n.init({
...defaultI18nextConfig,
lng: 'en',
resources: translations,
});
}
switchLanguage() {
const newLanguage = this.i18n.language === 'en' ? 'pt' : 'en';
this.i18n.changeLanguage(newLanguage);
}
translate(key) {
return this.i18n.t(key);
}
}
export const i18nService = new I18nService();
App.js
import React from 'react';
import { i18nService } from './i18nService';
const App = () => {
const switchLanguage = () => {
i18nService.switchLanguage();
};
return (
<div>
<button onClick={switchLanguage}>Switch Language</button>
<p>{i18nService.translate('Home')}</p>
<p>{i18nService.translate('Admin')}</p>
<p>{i18nService.translate('Reporting')}</p>
</div>
);
};
export default App;
Installation
To enable this module in your application, follow the steps below.
- Add
@genesislcap/foundation-i18n
as a dependency in yourpackage.json
file.
{
"dependencies": {
"@genesislcap/foundation-i18n": "latest"
},
}
- Run the
$ npm run bootstrap
command again. (Whenever you change the dependencies of your project, you should always run this command to rebuild.) You can find more information in the package.json basics page.