Awesome
ngx-easy-i18n-js
Pure version angular for internalization (i18n).
Translations are static. If you change language you must refresh the page or use bootstrap extension.
Use EasyI18 Js library https://github.com/gabrie-allaigre/easy-i18n-js
Download and Installation
Install using npm:
npm install easy-i18n-js @ngx-easy-i18n-js/core --save
Open angular.json and under allowedCommonJsDependencies add:
"allowedCommonJsDependencies": [
"easy-i18n-js"
]
Usage in app.module.ts, add imports
import localeFr from '@angular/common/locales/fr';
import localeEn from '@angular/common/locales/en';
imports: [
EasyI18nModule.forRoot({
options: {
logging: false
},
ngLocales: {
'fr': localeFr,
'en': localeEn,
},
defaultLanguage: 'en-US'
})
]
Configuration
export interface EasyI18nModuleConfig {
// Options fo easy i18 js library
options?: EasyI18nOptions;
// Use specific loader
loader?: Provider;
// Add Angular locale <code>import localeFr from '@angular/common/locales/fr';</code>
ngLocales?: { [key: string]: any; };
// Use browser language
useBrowserLanguage?: boolean;
// Default fallback language use if current language not found
defaultLanguage?: string;
// <code>exact</code> only fr-FR, <code>minimum</code> only fr, <code>all</code> fr-FR and fr
discover?: 'exact' | 'minimum' | 'all';
}
In child module
imports: [
EasyI18nModule
]
For change current locale use EasyI18nService
export class MyComponent {
constructor(
private easyI18nService: EasyI18nService
) {
}
public doChangeLanguage(locale: string): void {
this.easyI18nService.registerCulture('fr');
}
}
Force reload if change culture
this.easyI18nService.registerCulture('fr', { reload: true });
Locale pipes
In HTML, uses locales pipes to get dates, numbers in locale format
pipe | description | example |
---|---|---|
localeDate | Same as date | <code>{{ mydate | localeDate:'short' }}</code> |
localeNumber | Same as number | <code>{{ mydate | localeNumber }}</code> |
localeCurrency | Same as currency | <code>{{ mydate | localeCurrency }}</code> |
localePercent | Same as percent | <code>{{ mydate | localePercent }}</code> |
Translate
Main function for translate your language keys
HTML file
In HTML template, with pipe, parameter is TrOptions
{{ 'hello' | tr }}
{{ 'hello_with_genre' | tr: { gender: 'male' } }}
{{ 'My name is {}' | tr: { args: ['Gabriel'] } }}
TrOptions arguments
Name | type | example |
---|---|---|
args | string[] | ['Gabriel', '20'] |
namedArgs | { [key: string]: string; } } | { name : 'Gabriel', age : '20' } |
namespace | string | 'common' |
gender | <code>'male' | 'female' | 'other'</code> | gender: 'other' |
Directives
There are 2 differents directives
First is simple, translate [tr]
Directive | description | example |
---|---|---|
tr | Active directive translate | <code><span tr>hello</span></code> |
trNamespace | Add namespace | <code><span tr trNamespace="common">hello</span></code> |
trKey | Set key (if empty use content) | <code><span tr trKey="hello" trNamespace="common"></span></code> |
trGender | Gender | <code><span tr trGender="male">hello_with_genre</span></code> |
trArgs | Arguments | <code><span tr [trArgs]="['Gabriel']">hello</span></code> |
trNamedArgs | Named arguments | <code><span tr [trNamedArgs]="{ name: 'Gabriel' }">hello</span></code> |
Second, use HTML named arguments [trContent]
, replace {namedArg}
with child element *trElement
Directive | description |
---|---|
trContent | Active content directive translate, get a key |
trNamespace | Add namespace |
trGender | Gender |
trArgs | Arguments |
trNamedArgs | Named arguments |
demarc | Change token start, end identifier |
Examples
<!-- "hello_name": "My name is {name}" -->
<div trContent="hello_name">
<span *trElement="'name'" style="color: red; font-size: 2rem; font-weight: bold">Gabriel</span>
</div>
<div trContent="My name is {name} and I live in {country}" style="color: blue;">
<span *trElement="'name'" style="color: red; font-size: 2rem; font-weight: bold">Gabriel</span>
<span *trElement="'country'">{{ var_country }}</span>
</div>
Typescript file
You can use extension methods of [String], you can also use tr() as a static function.
In typescript file, there is no need to inject EasyI18nService
'hello'.tr();
'hello_with_genre'.tr({ gender: 'male' });
tr('hello');
tr('hello_with_genre', { gender: 'male' });
Translate Plural
You can translate with pluralization. To insert a number in the translated string, use {}.
HTML file
In HTML template, with pipe, first parameter is number and second PluralOptions
{{ 'money' | plural:10 }}
{{ 'money_with_args' | plural:3: { args: ['Gabriel'] } }}
PluralOptions arguments
Name | type | example |
---|---|---|
args | string[] | ['Gabriel', '20'] |
namedArgs | { [key: string]: string; } } | { name : 'Gabriel', age : '20' } |
namespace | string | 'common' |
name | string | money |
numberFormatterFn | (value: number) => string | (value) => value.Precision(3) |
gender | <code>'male' | 'female' | 'other'</code> | gender: 'other' |
Directives
There are 2 different directives
First is simple, translate plural [plural]
Directive | description | example |
---|---|---|
plural | Active directive translate | <code><span [plural]="10">money</span></code> |
pluralNamespace | Add namespace | <code><span [plural]="100" pluralNamespace="common">money</span></code> |
pluralKey | Set key (if empty use content) | <code><span [plural]="100" pluralKey="money" pluralNamespace="common"></span></code> |
pluralGender | Gender | <code><span [plural]="1" pluralGender="male">money_with_genre</span></code> |
pluralArgs | Arguments | <code><span [plural]="5" [pluralArgs]="['Gabriel']">money</span></code> |
pluralNamedArgs | Named arguments | <code><span [plural]="13" [pluralNamedArgs]="{ name: 'Gabriel' }">money</span></code> |
pluralName | Name value | <code><span [plural]="4" pluralName="value">money</span></code> |
pluralNumberFormatterFn | Formatter function | <code><span [plural]="10000" [pluralNumberFormatterFn]="myFn">money</span></code> |
Second, use HTML named arguments [pluralContent]
, replace {namedArg}
with child element *pluralElement
Directive | description |
---|---|
pluralContent | Active content directive translate, get a key |
pluralValue | Active content directive translate, get a value |
pluralNamespace | Add namespace |
pluralGender | Gender |
pluralArgs | Arguments |
pluralNamedArgs | Named arguments |
pluralName | Name value |
pluralNumberFormatterFn | Formatter function |
demarc | Change token start, end identifier |
Examples
<!-- "money_content": {
"zero": "{name} not have money",
"one": "{name} have {money} dollar",
"two": "{name} have {money} dollars",
"many": "{name} have {money} dollars",
"other": "{name} have {money} dollars"
} -->
<div pluralContent="money_content" [pluralValue]="var_money" class="fst-italic text-gray-500">
<span *pluralElement="'name'" style="color: red; font-size: 2rem; font-weight: bold">Gabriel</span>
<span *pluralElement="'money'" style="color: blueviolet; font-weight: bold"
[style.font-size]="(var_money / 10) + 'vw'">{{ var_money }}</span>
</div>
Typescript file
You can use extension methods of [String], you can also use plural() as a static function.
In typescript file, there is no need to inject EasyI18nService
'money_args'.plural(0, { args: ['Gabriel'] });
'money_args'.plural(1.5, { args: ['Gabriel'] });
plural('money_args', { args: ['Gabriel'] });
Store
Default store is EmptyEasyI18nStore
Use localStorage
store, usage in app.module.ts, add provider
providers: [
{
provide: EasyI18nStore,
useFactory: () => new LocalStorageEasyI18nStore('current-lang')
}
]
Add HttpLoader
Standard
Load messages with HttpClient
Install using npm:
npm install @ngx-easy-i18n-js/http-loader --save
Usage in app.module.ts, add provider
providers: [
{
provide: EasyI18nLoader,
deps: [HttpClient],
useFactory: (httpClient: HttpClient) => new HttpEasyI18nLoader(httpClient)
}
]
Change prefix or suffix with options
new HttpEasyI18nLoader(httpClient, {
prefix: 'assets/',
suffix: '.json5'
});
new HttpEasyI18nLoader(httpClient, {
prefix: ['assets/common/i18n', 'assets/i18n'],
suffix: '.json5'
});
Scoped loader
Load multiples files with scope
Usage in app.module.ts, add provider
providers: [
{
provide: EasyI18nLoader,
deps: [HttpClient],
useFactory: (httpClient: HttpClient) => new ScopedHttpEasyI18nLoader(httpClient, [
{ prefix: `/assets/i18n/` },
{ prefix: ['assets/common/i18n', 'assets/i18n/common'], scope: 'common' },
{ prefix: `/assets/i18n/errors/`, scope: 'errors' }
])
}
]
{{ 'common.save' | tr }}
{{ 'errors.internal_server_error' | tr }}
Change suffix
new ScopedHttpEasyI18nLoader(httpClient, [
{ prefix: `/assets/i18n/` }
], {
suffix: '.json5'
});
Append scoped loader for lazy routes
const routes: Routes = [
{
path: 'login',
loadChildren: () => import('./login/login.module').then(m => m.LoginModule),
canActivate: [
appendScopedHttpEasyI18nLoader([
{ prefix: `/assets/i18n/login/`, scope: 'login' }
])
]
}
];
Add Bootstrap
Bootstrap application, refresh application when culture change without reload page
Install using npm:
npm install @angular/cdk @ngx-easy-i18n-js/bootstrap --save
Usage
imports: [
EasyI18nBootstrapModule.forRoot({
bootstrap: AppComponent
})
]
bootstrap: [EasyI18nBootstrapComponent]
And in index.html
, replace <app-root></app-root>
by <ngx-easy-i18n></ngx-easy-i18n>
For custom loading component
imports: [
EasyI18nBootstrapModule.forRoot({
bootstrap: AppComponent,
loadingComponent: MyLoadingComponent
})
]
bootstrap: [EasyI18nBootstrapComponent]