Quickstart
In this quick start you'll learn how to do a basic i18n setup.
Installation
npm install --save nestjs-i18n
Setup translation files
By default nestjs-i18n
uses the I18nJsonLoader
loader class. This loader reads translations from json
files. Create a folder named i18n
in the src
folder of your project.
package.json
package-lock.json
...
src
└── i18n
├── en
│ ├── events.json
│ └── test.json
└── nl
├── events.json
└── test.json
{
"HELLO": "Hello",
"PRODUCT": {
"NEW": "New Product: {name}"
},
"ENGLISH": "English",
"ARRAY": ["ONE", "TWO", "THREE"],
"cat": "Cat",
"cat_name": "Cat: {name}",
"set-up-password": {
"heading": "Hello, {username}",
"title": "Forgot password",
"followLink": "Please follow the link to set up your password"
},
"day_interval": {
"one": "Every day",
"other": "Every {count} days",
"zero": "Never"
},
"nested": "We go shopping: $t(test.day_interval, {{\"count\": {count} }})"
}
The i18n
folder isn't automatically copied to your dist
folder during the build process. To enable nestjs
to do this modify the compilerOptions
inside nest-cli.json
.
{
"collection": "@nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"assets": [
{ "include": "i18n/**/*", "watchAssets": true }
]
}
}
When using a monorepo structure don't forget to set the outDir
{
"collection": "@nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"assets": [
{
"include": "i18n/**/*",
"watchAssets": true,
+ "outDir": "dist/apps/api"
}
]
}
}
Module setup
import { Module } from '@nestjs/common';
import * as path from 'path';
import { I18nModule } from 'nestjs-i18n';
@Module({
imports: [
I18nModule.forRoot({
fallbackLanguage: 'en',
loaderOptions: {
path: path.join(__dirname, '/i18n/'),
watch: true,
},
}),
],
controllers: [],
})
export class AppModule {}
The I18nModule
is a global module. This means you'll only need to register the module once (in the root module). After that it's accessible throughout the whole application.
Setting the watch
option to true
in the loaderOptions
enables live reloading 🎉.
Add resolvers
Resolvers are used for getting the current language of our request. In basic web applications this is done via the Accept-Language
header. But in many cases you want to override this language by your logged in user settings, or some header you define yourself.
nestjs-i18n
comes with a set of built-in resolvers.
Name | Default value |
---|---|
QueryResolver | ['lang'] |
HeaderResolver | [] |
AcceptLanguageResolver | {matchType: 'strict-loose' |
CookieResolver | lang |
GraphQLWebsocketResolver | N/A |
GrpcMetadataResolver | ['lang'] |
To add resolvers add them to the resolvers
array in your I18nModule
options. The way nestjs-i18n
works it's going to resolve the language in order. So in this case it tries the QueryResolver
first, if it can't resolve a language it'll jump to the next one.
import { Module } from '@nestjs/common';
import * as path from 'path';
import {
AcceptLanguageResolver,
I18nJsonLoader,
I18nModule,
QueryResolver,
} from 'nestjs-i18n';
@Module({
imports: [
I18nModule.forRoot({
fallbackLanguage: 'en',
loaderOptions: {
path: path.join(__dirname, '/i18n/'),
watch: true,
},
resolvers: [
{ use: QueryResolver, options: ['lang'] },
AcceptLanguageResolver,
],
}),
],
controllers: [],
})
export class AppModule {}
It's possible to create your own resolvers! For example if you want to resolve the language from your logged-in user's settings. Please see the resolvers page for instructions.
Translate stuff 🎉
Now that we've setup everything we can start to do translations! The easiest way to do this is in your controller
.
import { Controller, Get } from '@nestjs/common';
import { I18n, I18nContext } from 'nestjs-i18n';
@Controller()
export class AppController {
@Get()
async getHello(@I18n() i18n: I18nContext) {
return await i18n.t('test.HELLO');
}
}