UNPKG

23.8 kBMarkdownView Raw
1# @ngx-translate/core [![Build Status](https://travis-ci.org/ngx-translate/core.svg?branch=master)](https://travis-ci.org/ngx-translate/core) [![npm version](https://badge.fury.io/js/%40ngx-translate%2Fcore.svg)](https://badge.fury.io/js/%40ngx-translate%2Fcore)
2
3The internationalization (i18n) library for Angular.
4
5Simple example using ngx-translate: https://stackblitz.com/github/ngx-translate/example
6
7Get the complete changelog here: https://github.com/ngx-translate/core/releases
8
9## Table of Contents
10* [Installation](#installation)
11* [Usage](#usage)
12 * [Import the TranslateModule](#1-import-the-translatemodule)
13 * [SharedModule](#sharedmodule)
14 * [Lazy loaded modules](#lazy-loaded-modules)
15 * [Configuration](#configuration)
16 * [AoT](#aot)
17 * [Define the default language for the application](#2-define-the-default-language-for-the-application)
18 * [Init the TranslateService for your application](#3-init-the-translateservice-for-your-application)
19 * [Define the translations](#4-define-the-translations)
20 * [Use the service, the pipe or the directive](#5-use-the-service-the-pipe-or-the-directive)
21 * [Use HTML tags](#6-use-html-tags)
22* [API](#api)
23 * [TranslateService](#translateservice)
24 * [Properties](#properties)
25 * [Methods](#methods)
26 * [Write & use your own loader](#write--use-your-own-loader)
27 * [Example](#example)
28 * [How to use a compiler to preprocess translation values](#how-to-use-a-compiler-to-preprocess-translation-values)
29 * [How to handle missing translations](#how-to-handle-missing-translations)
30 * [Example](#example-1)
31 * [Parser](#parser)
32 * [Methods](#methods)
33* [FAQ](#faq)
34 * [I'm getting an error `npm ERR! peerinvalid Peer [...]`](#im-getting-an-error-npm-err-peerinvalid-peer-)
35* [Plugins](#plugins)
36* [Editors](#editors)
37* [Additional Framework Support](#additional-framework-support)
38
39
40## Installation
41
42First you need to install the npm module:
43
44```sh
45npm install @ngx-translate/core --save
46```
47
48Choose the version corresponding to your Angular version:
49
50 Angular | @ngx-translate/core | @ngx-translate/http-loader
51 ----------- | ------------------- | --------------------------
52 8 | 12.x+ | 4.x+
53 7 | 11.x+ | 4.x+
54 6 | 10.x | 3.x
55 5 | 8.x to 9.x | 1.x to 2.x
56 4.3 | 7.x or less | 1.x to 2.x
57 2 to 4.2.x | 7.x or less | 0.x
58
59---
60
61**If you use SystemJS** to load your files, you can check the [plunkr example](https://plnkr.co/edit/XXwyUYS6ZL7qVD9I2l0g?p=preview) for a working setup that uses the cdn [https://unpkg.com/](https://unpkg.com/).
62If you're importing directly from `node_modules`, you should edit your systemjs config file and add `'@ngx-translate/core': 'node_modules/@ngx-translate/core/bundles'` in the map and `'@ngx-translate/core' : { defaultExtension: 'js' }` in packages.
63
64
65## Usage
66
67#### 1. Import the `TranslateModule`:
68
69Finally, you can use ngx-translate in your Angular project. You have to import `TranslateModule.forRoot()` in the root NgModule of your application.
70
71The [`forRoot`](https://angular.io/api/router/RouterModule#forroot) static method is a convention that provides and configures services at the same time.
72Make sure you only call this method in the root module of your application, most of the time called `AppModule`.
73This method allows you to configure the `TranslateModule` by specifying a loader, a parser and/or a missing translations handler.
74
75```ts
76import {BrowserModule} from '@angular/platform-browser';
77import {NgModule} from '@angular/core';
78import {TranslateModule} from '@ngx-translate/core';
79
80@NgModule({
81 imports: [
82 BrowserModule,
83 TranslateModule.forRoot()
84 ],
85 bootstrap: [AppComponent]
86})
87export class AppModule { }
88```
89
90##### SharedModule
91
92If you use a [`SharedModule`](https://angular.io/guide/sharing-ngmodules) that you import in multiple other feature modules,
93you can export the `TranslateModule` to make sure you don't have to import it in every module.
94
95```ts
96@NgModule({
97 exports: [
98 CommonModule,
99 TranslateModule
100 ]
101})
102export class SharedModule { }
103```
104
105> Note: Never call a `forRoot` static method in the `SharedModule`. You might end up with different instances of the service in your injector tree. But you can use `forChild` if necessary.
106
107##### Lazy loaded modules
108
109When you lazy load a module, you should use the `forChild` static method to import the `TranslateModule`.
110
111Since lazy loaded modules use a different injector from the rest of your application, you can configure them separately with a different loader/compiler/parser/missing translations handler.
112
113To make a child module extend translations from parent modules use `extend: true`. This will cause the service to also
114use translations from its parent module.
115
116You can also isolate the service by using `isolate: true`. In which case the service is a completely isolated instance (for translations, current lang, events, ...).
117Otherwise, by default, it will share its data with other instances of the service (but you can still use a different loader/compiler/parser/handler even if you don't isolate the service).
118
119```ts
120@NgModule({
121 imports: [
122 TranslateModule.forChild({
123 loader: {provide: TranslateLoader, useClass: CustomLoader},
124 compiler: {provide: TranslateCompiler, useClass: CustomCompiler},
125 parser: {provide: TranslateParser, useClass: CustomParser},
126 missingTranslationHandler: {provide: MissingTranslationHandler, useClass: CustomHandler},
127 isolate: true
128 })
129 ]
130})
131export class LazyLoadedModule { }
132```
133
134##### Configuration
135
136By default, there is no loader available. You can add translations manually using `setTranslation` but it is better to use a loader.
137You can write your own loader, or import an existing one.
138For example you can use the [`TranslateHttpLoader`](https://github.com/ngx-translate/http-loader) that will load translations from files using HttpClient.
139
140To use it, you need to install the http-loader package from @ngx-translate:
141
142```sh
143npm install @ngx-translate/http-loader --save
144```
145
146**NB: if you're still on Angular <4.3, please use Http from @angular/http with http-loader@0.1.0.**
147
148Once you've decided which loader to use, you have to setup the `TranslateModule` to use it.
149
150Here is how you would use the `TranslateHttpLoader` to load translations from "/assets/i18n/[lang].json" (`[lang]` is the lang that you're using, for english it could be `en`):
151
152```ts
153import {NgModule} from '@angular/core';
154import {BrowserModule} from '@angular/platform-browser';
155import {HttpClientModule, HttpClient} from '@angular/common/http';
156import {TranslateModule, TranslateLoader} from '@ngx-translate/core';
157import {TranslateHttpLoader} from '@ngx-translate/http-loader';
158import {AppComponent} from './app';
159
160// AoT requires an exported function for factories
161export function HttpLoaderFactory(http: HttpClient) {
162 return new TranslateHttpLoader(http);
163}
164
165@NgModule({
166 imports: [
167 BrowserModule,
168 HttpClientModule,
169 TranslateModule.forRoot({
170 loader: {
171 provide: TranslateLoader,
172 useFactory: HttpLoaderFactory,
173 deps: [HttpClient]
174 }
175 })
176 ],
177 bootstrap: [AppComponent]
178})
179export class AppModule { }
180```
181
182##### AoT
183
184If you want to configure a custom `TranslateLoader` while using [AoT compilation](https://angular.io/docs/ts/latest/cookbook/aot-compiler.html) or [Ionic](http://ionic.io/), you must use an exported function instead of an inline function.
185
186```ts
187export function createTranslateLoader(http: HttpClient) {
188 return new TranslateHttpLoader(http, './assets/i18n/', '.json');
189}
190
191@NgModule({
192 imports: [
193 BrowserModule,
194 HttpClientModule,
195 TranslateModule.forRoot({
196 loader: {
197 provide: TranslateLoader,
198 useFactory: (createTranslateLoader),
199 deps: [HttpClient]
200 }
201 })
202 ],
203 bootstrap: [AppComponent]
204})
205export class AppModule { }
206```
207
208#### 2. Define the `default language` for the application
209
210```ts
211@NgModule({
212 imports: [
213 BrowserModule,
214 TranslateModule.forRoot({
215 defaultLanguage: 'en'
216 })
217 ],
218 providers: [
219
220 ],
221 bootstrap: [AppComponent]
222})
223export class AppModule { }
224```
225
226#### 3. Init the `TranslateService` for your application:
227
228```ts
229import {Component} from '@angular/core';
230import {TranslateService} from '@ngx-translate/core';
231
232@Component({
233 selector: 'app',
234 template: `
235 <div>{{ 'HELLO' | translate:param }}</div>
236 `
237})
238export class AppComponent {
239 param = {value: 'world'};
240
241 constructor(translate: TranslateService) {
242 // this language will be used as a fallback when a translation isn't found in the current language
243 translate.setDefaultLang('en');
244
245 // the lang to use, if the lang isn't available, it will use the current loader to get them
246 translate.use('en');
247 }
248}
249```
250
251#### 4. Define the translations:
252
253Once you've imported the `TranslateModule`, you can put your translations in a json file that will be imported with the `TranslateHttpLoader`. The following translations should be stored in `en.json`.
254
255```json
256{
257 "HELLO": "hello {{value}}"
258}
259```
260
261You can also define your translations manually with `setTranslation`.
262
263```ts
264translate.setTranslation('en', {
265 HELLO: 'hello {{value}}'
266});
267```
268
269The `TranslateParser` understands nested JSON objects. This means that you can have a translation that looks like this:
270
271```json
272{
273 "HOME": {
274 "HELLO": "hello {{value}}"
275 }
276}
277```
278
279You can then access the value by using the dot notation, in this case `HOME.HELLO`.
280
281#### 5. Use the service, the pipe or the directive:
282
283You can either use the `TranslateService`, the `TranslatePipe` or the `TranslateDirective` to get your translation values.
284
285With the **service**, it looks like this:
286
287```ts
288translate.get('HELLO', {value: 'world'}).subscribe((res: string) => {
289 console.log(res);
290 //=> 'hello world'
291});
292```
293
294This is how you do it with the **pipe**:
295
296```html
297<div>{{ 'HELLO' | translate:param }}</div>
298```
299
300And in your component define `param` like this:
301```ts
302param = {value: 'world'};
303```
304
305You can construct the translation keys dynamically by using simple string concatenation inside the template:
306
307```html
308<ul *ngFor="let language of languages">
309 <li>{{ 'LANGUAGES.' + language | translate }}</li>
310</ul>
311```
312
313Where `languages` is an array member of your component:
314
315```ts
316languages = ['EN', 'FR', 'BG'];
317```
318
319You can also use the output of the built-in pipes `uppercase` and `lowercase` in order to guarantee that your dynamically generated translation keys are either all uppercase or all lowercase. For example:
320
321```html
322<p>{{ 'ROLES.' + role | uppercase | translate }}</p>
323```
324
325```ts
326role = 'admin';
327```
328
329will match the following translation:
330```json
331{
332 "ROLES": {
333 "ADMIN": "Administrator"
334 }
335}
336```
337
338This is how you use the **directive**:
339```html
340<div [translate]="'HELLO'" [translateParams]="{value: 'world'}"></div>
341```
342
343Or even simpler using the content of your element as a key:
344```html
345<div translate [translateParams]="{value: 'world'}">HELLO</div>
346```
347
348#### 6. Use HTML tags:
349
350You can easily use raw HTML tags within your translations.
351
352```json
353{
354 "HELLO": "Welcome to my Angular application!<br><strong>This is an amazing app which uses the latest technologies!</strong>"
355}
356```
357
358To render them, simply use the `innerHTML` attribute with the pipe on any element.
359
360```html
361<div [innerHTML]="'HELLO' | translate"></div>
362```
363
364## API
365
366### TranslateService
367
368#### Properties:
369
370- `currentLang`: The lang currently used
371- `currentLoader`: An instance of the loader currently used (static loader by default)
372- `onLangChange`: An EventEmitter to listen to lang change events. A `LangChangeEvent` is an object with the properties `lang: string` & `translations: any` (an object containing your translations).
373
374 example:
375 ```ts
376 onLangChange.subscribe((event: LangChangeEvent) => {
377 // do something
378 });
379 ```
380- `onTranslationChange`: An EventEmitter to listen to translation change events. A `TranslationChangeEvent` is an object with the properties `lang: string` & `translations: any` (an object containing your translations).
381
382 example:
383 ```ts
384 onTranslationChange.subscribe((event: TranslationChangeEvent) => {
385 // do something
386 });
387 ```
388- `onDefaultLangChange`: An EventEmitter to listen to default lang change events. A `DefaultLangChangeEvent` is an object with the properties `lang: string` & `translations: any` (an object containing your translations).
389
390 example:
391 ```ts
392 onDefaultLangChange.subscribe((event: DefaultLangChangeEvent) => {
393 // do something
394 });
395 ```
396
397#### Methods:
398
399- `setDefaultLang(lang: string)`: Sets the default language to use as a fallback
400- `getDefaultLang(): string`: Gets the default language
401- `use(lang: string): Observable<any>`: Changes the lang currently used
402- `getTranslation(lang: string): Observable<any>`: Gets an object of translations for a given language with the current loader
403- `setTranslation(lang: string, translations: Object, shouldMerge: boolean = false)`: Manually sets an object of translations for a given language, set `shouldMerge` to true if you want to append the translations instead of replacing them
404- `addLangs(langs: Array<string>)`: Add new langs to the list
405- `getLangs()`: Returns an array of currently available langs
406- `get(key: string|Array<string>, interpolateParams?: Object): Observable<string|Object>`: Gets the translated value of a key (or an array of keys) or the key if the value was not found
407- `getStreamOnTranslationChange(key: string|Array<string>, interpolateParams?: Object): Observable<string|Object>`: Returns a stream of translated values of a key (or an array of keys) or the key if the value was not found. Without any `onTranslationChange` events this returns the same value as `get` but it will also emit new values whenever the translation changes.
408- `stream(key: string|Array<string>, interpolateParams?: Object): Observable<string|Object>`: Returns a stream of translated values of a key (or an array of keys) or the key if the value was not found. Without any `onLangChange` events this returns the same value as `get` but it will also emit new values whenever the used language changes.
409- `instant(key: string|Array<string>, interpolateParams?: Object): string|Object`: Gets the instant translated value of a key (or an array of keys). /!\ This method is **synchronous** and the default file loader is asynchronous. You are responsible for knowing when your translations have been loaded and it is safe to use this method. If you are not sure then you should use the `get` method instead.
410- `set(key: string, value: string, lang?: string)`: Sets the translated value of a key
411- `reloadLang(lang: string): Observable<string|Object>`: Calls resetLang and retrieves the translations object for the current loader
412- `resetLang(lang: string)`: Removes the current translations for this lang. /!\ You will have to call `use`, `reloadLang` or `getTranslation` again to be able to get translations
413- `getBrowserLang(): string | undefined`: Returns the current browser lang if available, or undefined otherwise
414- `getBrowserCultureLang(): string | undefined`: Returns the current browser culture language name (e.g. "de-DE" if available, or undefined otherwise
415
416#### Write & use your own loader
417
418If you want to write your own loader, you need to create a class that implements `TranslateLoader`. The only required method is `getTranslation` that must return an `Observable`. If your loader is synchronous, just use [`Observable.of`](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/of.md) to create an observable from your static value.
419
420##### Example
421
422```ts
423class CustomLoader implements TranslateLoader {
424 getTranslation(lang: string): Observable<any> {
425 return Observable.of({KEY: 'value'});
426 }
427}
428```
429
430Once you've defined your loader, you can provide it in your configuration by adding it to its `providers` property.
431
432```ts
433@NgModule({
434 imports: [
435 BrowserModule,
436 TranslateModule.forRoot({
437 loader: {provide: TranslateLoader, useClass: CustomLoader}
438 })
439 ],
440 bootstrap: [AppComponent]
441})
442export class AppModule { }
443```
444[Another custom loader example with translations stored in Firebase](FIREBASE_EXAMPLE.md)
445
446#### How to use a compiler to preprocess translation values
447
448By default, translation values are added "as-is". You can configure a `compiler` that implements `TranslateCompiler` to pre-process translation values when they are added (either manually or by a loader). A compiler has the following methods:
449
450- `compile(value: string, lang: string): string | Function`: Compiles a string to a function or another string.
451- `compileTranslations(translations: any, lang: string): any`: Compiles a (possibly nested) object of translation values to a structurally identical object of compiled translation values.
452
453Using a compiler opens the door for powerful pre-processing of translation values. As long as the compiler outputs a compatible interpolation string or an interpolation function, arbitrary input syntax can be supported.
454
455
456#### How to handle missing translations
457
458You can setup a provider for the `MissingTranslationHandler` in the bootstrap of your application (recommended), or in the `providers` property of a component. It will be called when the requested translation is not available. The only required method is `handle` where you can do whatever you want. If this method returns a value or an observable (that should return a string), then this will be used. Just don't forget that it will be called synchronously from the `instant` method.
459
460You can use `useDefaultLang` to decide whether default language string should be used when there is a missing translation in current language. Default value is true. If you set it to false, `MissingTranslationHandler` will be used instead of the default language string.
461
462##### Example:
463
464Create a Missing Translation Handler
465
466```ts
467import {MissingTranslationHandler, MissingTranslationHandlerParams} from '@ngx-translate/core';
468
469export class MyMissingTranslationHandler implements MissingTranslationHandler {
470 handle(params: MissingTranslationHandlerParams) {
471 return 'some value';
472 }
473}
474```
475
476Setup the Missing Translation Handler in your module import by adding it to the `forRoot` (or `forChild`) configuration.
477
478```ts
479@NgModule({
480 imports: [
481 BrowserModule,
482 TranslateModule.forRoot({
483 missingTranslationHandler: {provide: MissingTranslationHandler, useClass: MyMissingTranslationHandler},
484 useDefaultLang: false
485 })
486 ],
487 providers: [
488
489 ],
490 bootstrap: [AppComponent]
491})
492export class AppModule { }
493```
494
495### Parser
496
497If you need it for some reason, you can use the `TranslateParser` service.
498
499#### Methods:
500- `interpolate(expr: string | Function, params?: any): string`: Interpolates a string to replace parameters or calls the interpolation function with the parameters.
501
502 `This is a {{ key }}` ==> `This is a value` with `params = { key: "value" }`
503 `(params) => \`This is a ${params.key}\` ==> `This is a value` with `params = { key: "value" }`
504- `getValue(target: any, key: string): any`: Gets a value from an object by composed key
505 `parser.getValue({ key1: { keyA: 'valueI' }}, 'key1.keyA') ==> 'valueI'`
506
507## FAQ
508
509#### I'm getting an error `npm ERR! peerinvalid Peer [...]`
510
511If you're using npm 2.x, upgrade to npm 3.x, because npm 2 doesn't handle peer dependencies well. With npm 2 you could only use fixed versions, but with npm 3 you can use `^` to use a newer version if available.
512
513If you're already on npm 3, check if it's an error (`npm ERR!`) or a warning (`npm WARN!`), warning are just informative and if everything works then don't worry !
514
515If you're using an old version of Angular and ngx-translate requires a newer version then you should consider upgrading your application to use the newer angular 2 version. There is always a reason when I upgrade the minimum dependencies of the library. Often it is because Angular had a breaking changes. If it's not an option for you, then check [the changelog](/releases) to know which version is the last compatible version for you.
516
517#### I want to hot reload the translations in my application but `reloadLang` does not work
518
519If you want to reload the translations and see the update on all your components without reloading the page, you have to load the translations manually and call `setTranslation` function which triggers `onTranslationChange`.
520
521## Plugins
522- [Localize Router](https://github.com/Greentube/localize-router) by @meeroslav: An implementation of routes localization for Angular. If you need localized urls (for example /fr/page and /en/page).
523- [.po files Loader](https://github.com/biesbjerg/ngx-translate-po-http-loader) by @biesbjerg: Use .po translation files with ngx-translate
524- [ngx-translate-extract](https://github.com/biesbjerg/ngx-translate-extract) by @biesbjerg: Extract translatable strings from your projects
525- [MessageFormat Compiler](https://github.com/lephyrus/ngx-translate-messageformat-compiler) by @lephyrus: Compiler for ngx-translate that uses messageformat.js to compile translations using ICU syntax for handling pluralization, gender, and more
526- [ngx-translate-zombies](https://marketplace.visualstudio.com/items?itemName=seveseves.ngx-translate-zombies) by @seveves: A vscode extension that finds unused translation keys and shows them in a diff view (so called zombies).
527- [ngx-translate-multi-http-loader](https://github.com/denniske/ngx-translate-multi-http-loader) by @denniske: Fetch multiple translation files with ngx-translate.
528- [ngx-translate-cache](https://github.com/jgpacheco/ngx-translate-cache) by @jgpacheco: Simplified version of localize-router. If you are already using localize-router you don't need this extension. This extension is aimed only to facilitate language caching.
529- [ngx-translate-module-loader](https://github.com/larscom/ngx-translate-module-loader) by @larscom: Fetch multiple translation files (http) with ngx-translate. Each translation file gets it's own namespace out of the box and the configuration is very flexible.
530- [ngx-translate-all](https://github.com/irustm/ngx-translate-all) by @irustm: Automate translations for Angular projects.
531- [ngx-translate-migrate](https://github.com/irustm/ngx-translate-migrate) by @irustm: Automate migrations from ngx-translate to Angular i18n.
532- [ngx-translate-lint](https://github.com/svoboda-rabstvo/ngx-translate-lint) by @svoboda-rabstvo: Simple CLI tools for check ngx-translate keys in whole app
533- [ngx-translate-cut](https://github.com/bartholomej/ngx-translate-cut) by @bartholomej: Simple and useful pipe for cutting translations ✂️
534
535## Editors
536- [BabelEdit](https://www.codeandweb.com/babeledit) — translation editor for JSON files
537- [Translation Manager](https://translation-manager-86c3d.firebaseapp.com/) — Progressive web-app, translation editor for JSON files
538
539### Extensions
540
541#### VScode
542- [Generate Translation](https://marketplace.visualstudio.com/items?itemName=thiagocordeirooo.generate-translation) by [@thiagocordeirooo](https://github.com/thiagocordeirooo): A visual studio code extension for you to generate the translations without leaving the current file.
543
544
545## Additional Framework Support
546
547* [Use with NativeScript](https://github.com/NathanWalker/nativescript-ng2-translate/issues/5#issuecomment-257606661)