jorgecoca / nestjs-i18n

Add i18n support inside your nestjs project

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Build Status Greenkeeper badge

Description

The i18n module for Nest.

Installation

$ npm i --save nestjs-i18n

Quick Start

Structure

create a directory and in it define your language keys as directories.

i18n
├── en
│   ├── category.json
│   └── auth.json
└── nl
    ├── category.json
    └── auth.json

Translation File

The format for the translation file could look like this:

{
  "HELLO_MESSAGE": "Hello {username}",
  "GOODBYE_MESSAGE": "Goodbye {username}",
  "USER_ADDED_PRODUCT": "{0.username} added {1.productName} to cart",
  "SETUP": {
    "WELCOME": "Welcome {0.username}",
    "GOODBYE": "Goodbye {0.username}"
  },
  "ARRAY": [
    "ONE",
    "TWO",
    "THREE"
  ]
}

String formatting is done by: string-format

Translation Module

To use the translation service we first add the module. The I18nModule has an @Global() attribute so you should only import it once.

import { Module } from '@nestjs/common';
import * as path from 'path';
import { I18nModule } from 'nestjs-i18n';

@Module({
  imports: [
    I18nModule.forRoot({
      path: path.join(__dirname, '/i18n'), 
      filePattern: '*.json',
      fallbackLanguage: 'en',
    }),
  ],
  controllers: []
})
export class AppModule {}

Using forRootAsync()

import { Module } from '@nestjs/common';
import * as path from 'path';
import { I18nModule } from 'nestjs-i18n';

@Module({
  imports: [
    I18nModule.forRootAsync({ 
        useFactory: (config: ConfigurationService) => ({ 
          path: configService.i18nPath, 
          fallbackLanguage: configService.fallbackLanguage, // e.g., 'en'
          filePattern: configService.i18nFilePattern, // e.g., '*.i18n.json'
        }),
        inject: [ConfigurationService] 
    }),
  ],
  controllers: []
})
export class AppModule {}

Language Resolvers

To make it easier to manage in what language to respond you can make use of resolvers

@Module({
  imports: [
    I18nModule.forRoot({
      path: path.join(__dirname, '/i18n/'),
      fallbackLanguage: 'en',
      resolvers: [
        new QueryResolver(['lang', 'locale', 'l']),
        new HeaderResolver(),
      ],
    }),
  ],
  controllers: [HelloController],
})
export class AppModule {}

Currently, there are two build-in resolvers

Resolver Default value
QueryResolver none
HeaderResolver accept-language

To implement your own resolver (or custom logic) use the I18nResolver interface.

Using Translation Service and Language Resolver

@Controller()
export class SampleController {

  constructor(
    private readonly i18n: I18nService,
  ) {}

  @Get()
  sample(
    @I18nLang() lang: string
  ) {
    this.i18n.translate('HELLO_MESSAGE', {lang: lang, args: {id: 1, username: 'Toon'}});
    this.i18n.translate('SETUP.WELCOME', {lang: 'en', args: {id: 1, username: 'Toon'}});
    this.i18n.translate('ARRAY.0', {lang: 'en'});
  }
}

Missing Translations

If you require a translation that is missing, I18n will log an error. However, you can also write these missing translations to a new file in order to help translating your application later on.

This behaviour can be controlled via the saveMissing: boolean attribute when adding the I18nModule to your application. Thereby, true describes the following behaviour:

Say, you request the translation mail.registration.subject in a de language, and this specific key is missing. This will create a de/mail.missing file in your i18n folder and add the following content:

{
  "registration": {
    "subject": ""
  }
}

CLI

To easily check if your i18n folder is correctly structured you can use the following command: nest-i18n check <i18n-path>

example: nest-i18n check src/i18n

This is very useful inside a CI environment to prevent releases with missing translations.

Breaking changes:

  • from V4.0.0 on we changed the signature of the translate method, the language is now optional, if no language is given it'll fallback to the fallbackLanguage

  • from V3.0.0 on we load translations based on their directory name instead of file name. Change your translations files to the structure above: info

About

Add i18n support inside your nestjs project

License:Other


Languages

Language:TypeScript 98.2%Language:JavaScript 1.8%