Socket
Socket
Sign inDemoInstall

angular-i18next

Package Overview
Dependencies
Maintainers
1
Versions
93
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

angular-i18next

i18next module for Angular


Version published
Weekly downloads
18K
increased by9.42%
Maintainers
1
Weekly downloads
 
Created
Source

npm version Downloads Build Status Coverage Status Commitizen friendly Dependency Status devDependency Status

angular-i18next

i18next v8.4+ integration with angular v2.0+

Features

  • Native i18next options
  • Promise initialization
  • i18next plugin support
  • Events support
  • Namespaces lazy load
  • i18next native format support
  • document.title localization
  • Error handling strategies
  • i18next namespaces and scopes (prefixes) for angular modules and components
  • AOT support

Installation

1. Install package npm install angular-i18next --save

2. Import I18NextModule to AppModule


import { I18NextModule } from 'angular-i18next';

@NgModule({
  bootstrap: [ AppComponent ],
  declarations: [   
    AppComponent
  ],
  import: [
    I18NextModule.forRoot()
  ]
})
export class AppModule {}

3. Inject I18NextService to AppComponent and call "init" method (with prefered options). We recommend to use more advanced and prefered initialization.


import { I18NextService } from 'angular-i18next';

export class AppComponent {

  constructor(@Inject(I18NEXT_SERVICE) private i18NextService: ITranslationService) {
      i18NextService.init({
        whitelist: ['en', 'ru'],
        fallbackLng: 'en',
        debug: true,
        returnEmptyString: false,
        ns: [
          'translation',
          'validation',
          'error'          
        ],
      });
  }

Usage

Pipes

Use "i18next" pipe to translate key:

<div>{{ 'test' | i18next }}</div>

Passing "t options":

<div>{{ 'test' | i18next: { count: 5, nsSeparator: '#' } }}</div>

Trigger native i18next format method by using I18NextFormatPipe or I18NextPipe with option 'format':

{{ 'any_key' | i18next | i18nextFormat }}

{{ 'any_key' | i18next: { format: 'cap' } }}

{{ 'any_key' | i18nextCap }}

Note: Using "i18nextCap" you will get the same result as i18next: { format: 'cap' }

REMEMBER that format will not work until you set "interpolation.format" function in i18next options.

I18NextModule has static method static interpolationFormat(customFormat: Function = null): Function that can be used as default interpolation format function (it provides 'upper', 'cap' and 'lower' formatters). You also can pass your custom function to be called after I18NextModule formatters:

const i18nextOptions = {
  whitelist: ['en', 'ru'],
  ns: [
    'translation',
    'validation',
    'error',
  ],
  interpolation: {
    format: I18NextModule.interpolationFormat((value, format, lng) => {
      if(value instanceof Date)
        return moment(value).format(format);
      return value;
    });
    // format: I18NextModule.interpolationFormat()
  }
};

Subscribing to event observables:

this.i18NextService.events.languageChanged.subscribe(lang => {
  // do something
})

Add a provider to module/component if you want to prefix child i18next keys:

{
  provide: I18NEXT_NAMESPACE,
  useValue: 'feature' // set 'feature:' prefix 
}
{
  provide: I18NEXT_SCOPE,
  useValue: 'person' // set 'person.' prefix 
}

Version: 3.1.0

It is possible to pass array of namespaces (or scopes). Key would fallback to next namespace in array if the previous failed to resolve.

[feature.validators:key, validators:key]

{
  provide: I18NEXT_NAMESPACE,
  useValue: ['feature.validators', 'validators']
}

If you want to turn on document title localization resolve Title as I18NextTile imported from 'angular-i18next':

  provide: Title,
  useClass: I18NextTitle
}```

Also you can implement your own Title service with specific behavior. Inject I18NextPipe (or I18NextService) to service/component:
```typescript
import { Injectable, Inject } from '@angular/core';
import { Title, DOCUMENT } from '@angular/platform-browser';
import { I18NextPipe } from './I18NextPipe';

@Injectable()
export class I18NextTitle extends Title {
   constructor(private i18nextPipe: I18NextPipe, @Inject(DOCUMENT) doc) {
    super(doc);
   }

   setTitle(value: string) {
    return super.setTitle(this.translate(value));
   }

   private translate(text: string) {
     return this.i18nextPipe.transform(text, { format: 'cap'});
   }
}

Ways to use I18NextService in your code:

Warning: Injection of I18NextService is possible, but it would not consider I18NEXT_NAMESPACE and I18NEXT_SCOPE providers. There are 2 possible reasons to inject I18NextService: initialization and subscribtion to its events. In all other cases inject I18NextPipe.

  1. Recommended way: Inject via I18NEXT_SERVICE token. By default it will inject instance of I18NextService.
export class AppComponent implements OnInit  {
  constructor(private router: Router,
              private title: Title,
              @Inject(I18NEXT_SERVICE) private i18NextService: ITranslationService) 
  1. Legacy way: Inject via type
export class AppComponent implements OnInit  {
  constructor(private router: Router,
              private title: Title,
              private i18NextService: I18NextService) 

Error handling

Error handling is now configurable:

  1. By default i18next promise will use NativeErrorHandlingStrategy. I18Next would be always resolve succesfully. Error could be get from 'then' handler parameter.
  2. Set StrictErrorHandlingStrategy to reject load promises (init, languageChange, loadNamespaces) on first load fail (this was default in v2 but changed to fit native i18next behavior:
`I18NextModule.forRoot({ errorHandlingStrategy: StrictErrorHandlingStrategy })`

Lazy loading

Use I18NEXT_NAMESPACE_RESOLVER in your routes to to load i18next namespace.

Note: It is not neccesary to register lazy loading namespaces in global i18next options.

{
    path: 'rich_form',
    loadChildren: 'app/features/rich_form_feature/RichFormFeatureModule#RichFormFeatureModule',
    data: {
      i18nextNamespaces: ['feature.rich_form']
    },
    resolve: {
      i18next: I18NEXT_NAMESPACE_RESOLVER
    }
 },

Use I18NextService.loadNamespaces() method to load namespaces in code.

Cookbook

i18next plugin support

import { I18NextModule, ITranslationService, I18NEXT_SERVICE } from 'angular-i18next';
import * as i18nextXHRBackend from 'i18next-xhr-backend';
import * as i18nextLanguageDetector from 'i18next-browser-languagedetector';

...

i18next.use(i18nextXHRBackend)
       .use(i18nextLanguageDetector)
       .init(i18nextOptions)

Initialize i18next before angular application

Angular would not load until i18next initialize event fired

export function appInit(i18next: ITranslationService) {
    return () => i18next.init();
}

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
}];

Document title update on language or route change

export class AppComponent implements OnInit  {
  constructor(private router: Router,
              private title: Title,
              @Inject(I18NEXT_SERVICE) private i18NextService: ITranslationService) {
      // page title subscription
      // https://toddmotto.com/dynamic-page-titles-angular-2-router-events#final-code
      this.router.events
        .filter(event => event instanceof NavigationEnd)
        .map(() => this.router.routerState.root)
        .map(route => {
          while (route.firstChild) route = route.firstChild;
          return route;
        })
        .filter(route => route.outlet === 'primary')
        .mergeMap(route => route.data)
        .subscribe((event) => this.updatePageTitle(event['title']));
  }

  ngOnInit() {
    this.i18NextService.events.languageChanged.subscribe(lang => {
      let root = this.router.routerState.root;
      if (root != null && root.firstChild != null) {
        let data: any = root.firstChild.data;
        this.updatePageTitle(data && data.value && data.value.title);
      }
    });
  }

  updatePageTitle(title: string): void {
    let newTitle = title || 'application_title';
    this.title.setTitle(newTitle);
  }
}

Routes example:

const appRoutes: Routes = [
  { 
    path: 'error',
    component: AppErrorComponent,
    data: { title: 'error:error_occured' }
  },
  { 
    path: 'denied',
    component: AccessDeniedComponent,
    data: { title: 'error:access_denied' }
  }
];

Demo

Demo app source code now awailable: https://github.com/Romanchuk/angular-i18next-demo

It's not yet deployed as public web site.

To run:

npm install
npm start

Migration to v3

To keep same behavior you should:

  1. update i18next version to >= 8.4.0
  2. set options.interpolation.format: I18NextModule.interpolationFormat()
  3. set I18NextModule.forRoot params to:

I18NextModule.forRoot({ localizeTitle: true, errorHandlingStrategy: StrictErrorHandlingStrategy })

Migration to v3.2.0

  • 'localizeTitle' option was removed. You need to resolve Title service manually.

v2 docs available here

Breaking changes list

  • Added i18NextFormat pipe to support i18next

  • BREAKING: Reserved option 'case' in I18NextPipe changed to 'format'

  • BREAKING: I18NextCapPipe has no own formaters

  • I18NextModule has static method static interpolationFormat(customFormat: Function = null): Function that can be used as default interpolation format (it provides 'upper', 'cap' and 'lower' formatters) . You also can pass your custom function to be called after I18NextModule formatters .

  • i18next version support >= 8.4.0

  • Title provider does not resolving as I18NextTitle by default anymore

  • Fix #9

Keywords

FAQs

Package last updated on 04 Feb 2018

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc