How to Implement Internationalization (i18n) in NestJS

Updated: January 1, 2024 By: Guest Contributor Post a comment

Introduction

Internationalization, often abbreviated as i18n, allows applications to reach a broader, global audience by enabling the use of multiple languages and regional differences. This guide will walk you through setting up internationalization in a NestJS application using best practices and the latest TypeScript syntax.

Setting Up a New NestJS Project

Before diving into internationalization, let’s set up a new NestJS project. Ensure that you have Node.js installed, and then install the NestJS CLI globally using npm:

npm i -g @nestjs/cli

Create a new project with the following command:

nest new [project-name]

Navigate into your project directory and prepare it for the i18n setup:

cd [project-name]

Installing i18n Module

npm install nestjs-i18n

This command installs the necessary module to work with internationalization in NestJS.

Basic Configuration

Once the module is installed, you can start with a basic configuration. Inside your app.module.ts, import the I18nModule and configure it:

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

@Module({
  imports: [
    I18nModule.forRoot({
      fallbackLanguage: 'en',
      parser: I18nJsonParser,
      parserOptions: {
        path: path.join(__dirname, '/i18n/'),
      },
    }),
  ],
})
export class AppModule {}

Create an i18n directory in your project’s root with language JSON files named after the locale codes (e.g., en.json, fr.json).

Language Files

Each JSON file should contain key-value pairs representing your app’s strings in the corresponding language.

{
  "greeting": "Hello, World!"
}

And for another language, e.g. French:

{
  "greeting": "Bonjour le monde!"
}

Using i18n in Controllers

In your controllers, inject the I18nService to utilize the i18n features:

import { Controller, Get } from '@nestjs/common';
import { I18nService } from 'nestjs-i18n';

@Controller('hello')
export class HelloController {
  constructor(private readonly i18n: I18nService) {}

  @Get()
  async sayHello(): Promise {
    const message = await this.i18n.translate('greeting');
    return message;
  }
}

This example translates the ‘greeting’ key based on the request’s ‘Accept-Language’ header.

Advanced Usage

For more complex scenarios, like supporting region-specific languages (e.g., en-US vs. en-GB), you’ll need to enhance your i18n configuration:

{
  resolver: [new HeaderResolver(['x-custom-lang']), AcceptLanguageResolver],
  parserOptions: {
    path: path.join(__dirname, '/i18n/'),
    watch: true
  }
}

You can also combine translations and use variables within your language files:

{
  "greetingWithName": "Hello, {name}!"
}

Then in your controllers:

const username = 'Jane';
const message = await this.i18n.translate('greetingWithName', { args: { name: username } });

Testing Your Setup

To test your i18n setup, send a request to your endpoint and change the ‘Accept-Language’ header to see different translations.

Summary

Implementing internationalization with NestJS is straightforward once you set up the nestjs-i18n module. It provides a flexible and powerful way to support multiple languages, contributing significantly to the global reach of your application.