Internationalization (i18n) in JavaScript (Node.js)
Internationalization (abbreviated as i18n — from the English word "internationalization", where 18 represents the number of letters between the first "i" and the last "n") is the process of designing and developing software so that it can be easily adapted for different languages and regions without making changes to the code. In the Node.js ecosystem, there are several powerful libraries that significantly simplify this task. In this article, we will look at the two most popular ones: i18next and node-polyglot.
Why is internationalization needed?
Modern web applications and server-side services often work with users from different countries. Supporting multiple languages improves user experience (UX) and expands the audience. Without i18n, developers would have to hardcode strings in a single language, making multilingual support extremely labor-intensive and error-prone.
The main tasks solved by i18n libraries in Node.js:
- Support for translation files (usually JSON or YAML).
- Pluralization (correct word declension depending on the number: "1 coffee", "2 coffees", "5 coffees").
- Variable interpolation into strings (e.g., "Hello, {{name}}!").
- Support for nested keys to organize the translation structure.
- Automatic detection of the user's language (via HTTP headers, cookies, subdomains).
The i18next Library
i18next is arguably the most popular and feature-rich library for internationalization in the JavaScript world. It works both in the browser and on the Node.js server. i18next offers a rich ecosystem of plugins, including integration with React, Vue, Express, and other frameworks.
Installation and basic setup
// Installation via npmnpm install i18nextLet's create translation files. They are usually stored in the locales folder:
locales/ru/translation.json
{ "greeting": "Привет, {{name}}!", "coffee": "Вы выпили {{count}} чашку кофе", "coffee_plural": "Вы выпили {{count}} чашек кофе", "menu": { "home": "Главная", "about": "О нас" }}locales/en/translation.json
{ "greeting": "Hello, {{name}}!", "coffee": "You drank {{count}} cup of coffee", "coffee_plural": "You drank {{count}} cups of coffee", "menu": { "home": "Home", "about": "About us" }}Now let's initialize i18next in the application:
const i18next = require('i18next');const fs = require('fs');const path = require('path');
// Load translations from filesfunction loadTranslation(lng) { const filePath = path.join(__dirname, 'locales', lng, 'translation.json'); return JSON.parse(fs.readFileSync(filePath, 'utf8'));}
i18next.init({ lng: 'ru', // default language fallbackLng: 'en', // fallback language resources: { ru: { translation: loadTranslation('ru') }, en: { translation: loadTranslation('en') } }, interpolation: { escapeValue: false // no need to escape HTML for Node.js }});
// Usageconsole.log(i18next.t('greeting', { name: 'Алексей' }));// Output: Привет, Алексей!
console.log(i18next.t('coffee', { count: 1 }));// Output: Вы выпили 1 чашку кофе
console.log(i18next.t('coffee', { count: 5 }));// Output: Вы выпили 5 чашек кофе
console.log(i18next.t('menu.home'));// Output: ГлавнаяChanging language on the fly
i18next.changeLanguage('en');console.log(i18next.t('greeting', { name: 'Alex' }));// Output: Hello, Alex!The node-polyglot Library
node-polyglot is a lightweight and simple alternative to i18next. It is ideal for small projects or when not