I18next распространяется как независимая библиотека интернационализации для JavaScript-приложений. Базовая установка выполняется через npm:
npm install i18next
Для браузерного окружения без сборщика доступно подключение через CDN:
<script src="https://unpkg.com/i18next/dist/umd/i18next.min.js"></script>
После установки глобальный объект i18next становится
доступным для конфигурации и перевода строк.
Простейшая структура проекта с поддержкой локализации обычно выглядит следующим образом:
project/
├── index.js
├── locales/
│ ├── en/
│ │ └── translation.json
│ └── ru/
│ └── translation.json
└── package.json
Каталог locales содержит переводы для каждого языка.
Файл translation.json является стандартным namespace по
умолчанию.
Пример английской локализации:
{
"welcome": "Welcome",
"description": "Internationalization example"
}
Русская локализация:
{
"welcome": "Добро пожаловать",
"description": "Пример интернационализации"
}
Ключи должны совпадать между всеми языками. Изменяется только текст перевода.
Минимальная конфигурация I18next может быть выполнена прямо в основном файле приложения.
import i18next from 'i18next';
i18next.init({
lng: 'ru',
resources: {
en: {
translation: {
welcome: 'Welcome'
}
},
ru: {
translation: {
welcome: 'Добро пожаловать'
}
}
}
});
console.log(i18next.t('welcome'));
Результат:
Добро пожаловать
lngОпределяет активный язык приложения.
lng: 'ru'
Если установить:
lng: 'en'
то метод t() начнёт возвращать английские строки.
resourcesСодержит словари переводов.
Структура:
resources: {
язык: {
namespace: {
ключ: значение
}
}
}
Пример:
resources: {
en: {
translation: {
hello: 'Hello'
}
}
}
en — код языкаtranslation — namespacehello — ключHello — переводt()Главная функция библиотеки.
i18next.t('welcome');
Метод ищет ключ в активной локали и возвращает перевод.
Хранение переводов внутри init() подходит только для
демонстраций. В реальных проектах переводы выносятся в отдельные
файлы.
import i18next from 'i18next';
import en from './locales/en/translation.json';
import ru from './locales/ru/translation.json';
i18next.init({
lng: 'ru',
resources: {
en: {
translation: en
},
ru: {
translation: ru
}
}
});
Такой подход:
Fallback-язык используется, если перевод отсутствует в текущей локали.
i18next.init({
lng: 'ru',
fallbackLng: 'en',
resources: {
en: {
translation: {
title: 'Home page'
}
},
ru: {
translation: {}
}
}
});
Вызов:
i18next.t('title');
вернёт:
Home page
поскольку ключ отсутствует в русском словаре.
Если namespace не указан явно, I18next использует
translation.
resources: {
ru: {
translation: {
hello: 'Привет'
}
}
}
Обращение к ключу:
i18next.t('hello');
Если используется другой namespace:
resources: {
ru: {
common: {
hello: 'Привет'
}
}
}
то потребуется указание namespace:
i18next.t('common:hello');
Метод init() возвращает Promise.
Современный вариант инициализации:
import i18next from 'i18next';
await i18next.init({
lng: 'ru',
resources: {
ru: {
translation: {
hello: 'Привет'
}
}
}
});
console.log(i18next.t('hello'));
Такой подход особенно важен при загрузке переводов с сервера.
Язык можно менять во время работы приложения.
i18next.changeLanguage('en');
После переключения:
console.log(i18next.t('welcome'));
вернёт английский перевод.
Активный язык хранится в свойстве language.
console.log(i18next.language);
Результат:
ru
I18next поддерживает древовидную структуру переводов.
{
"menu": {
"home": "Главная",
"about": "О нас"
}
}
i18next.t('menu.home');
Результат:
Главная
Такой подход помогает структурировать большие словари.
Минимальная конфигурация уже поддерживает подстановку переменных.
{
"welcome": "Привет, {{name}}"
}
i18next.t('welcome', {
name: 'Алексей'
});
Результат:
Привет, Алексей
По умолчанию I18next экранирует HTML-символы для защиты от XSS.
Настройка:
interpolation: {
escapeValue: true
}
Во frontend-фреймворках вроде React экранирование часто отключают:
interpolation: {
escapeValue: false
}
React самостоятельно защищает DOM от большинства XSS-атак.
Простейший пример для серверного Jav * aScript:
import i18next from 'i18next';
await i18next.init({
lng: 'ru',
resources: {
ru: {
translation: {
error: 'Ошибка сервера'
}
}
}
});
console.log(i18next.t('error'));
I18next одинаково работает:
Старый вариант конфигурации использует callback-функцию.
i18next.init({
lng: 'ru',
resources: {
ru: {
translation: {
hello: 'Привет'
}
}
}
}, (err, t) => {
console.log(t('hello'));
});
Такой стиль встречается в старых проектах и legacy-коде.
Минимальная конфигурация может содержать сразу несколько локалей.
i18next.init({
lng: 'en',
resources: {
en: {
translation: {
save: 'Save'
}
},
ru: {
translation: {
save: 'Сохранить'
}
},
de: {
translation: {
save: 'Speichern'
}
}
}
});
Для диагностики можно включить режим debug.
i18next.init({
debug: true,
lng: 'ru',
resources: {}
});
I18next начнёт выводить информацию в консоль:
Если ключ отсутствует:
i18next.t('unknown_key');
по умолчанию возвращается сам ключ:
unknown_key
Это помогает быстро замечать пропущенные переводы.
Можно изменить поведение:
i18next.init({
returnNull: false,
returnEmptyString: false
});
Такая настройка предотвращает возврат null и пустых
строк.
Для браузеров часто используется плагин определения языка пользователя.
Установка:
npm install i18next-browser-languagedetector
Подключение:
import i18next from 'i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
i18next
.use(LanguageDetector)
.init({
fallbackLng: 'en',
resources: {
en: {
translation: {
hello: 'Hello'
}
},
ru: {
translation: {
hello: 'Привет'
}
}
}
});
Плагин анализирует:
В React обычно используется пакет react-i18next.
Установка:
npm install react-i18next
Конфигурация:
import i18next from 'i18next';
import { initReactI18next } from 'react-i18next';
i18next
.use(initReactI18next)
.init({
lng: 'ru',
fallbackLng: 'en',
resources: {
en: {
translation: {
hello: 'Hello'
}
},
ru: {
translation: {
hello: 'Привет'
}
}
}
});
Использование в компоненте:
import { useTranslation } from 'react-i18next';
function App() {
const { t } = useTranslation();
return <h1>{t('hello')}</h1>;
}
Практический минимальный шаблон:
import i18next from 'i18next';
import en from './locales/en/translation.json';
import ru from './locales/ru/translation.json';
await i18next.init({
lng: 'ru',
fallbackLng: 'en',
resources: {
en: {
translation: en
},
ru: {
translation: ru
}
},
interpolation: {
escapeValue: false
}
});
Такая конфигурация уже подходит для: