Файлы переводов формируют основу любой локализации в i18next и определяют, как именно приложение будет отделять языковую логику от бизнес-кода. На уровне структуры это обычные JSON-документы, в которых ключи соответствуют идентификаторам строк интерфейса, а значения — переведённому тексту или вложенным объектам с вариантами форм.
В простейшем виде файл перевода представляет собой плоский JSON-объект:
{
"welcome": "Добро пожаловать",
"logout": "Выйти",
"login": "Войти"
}
Такой формат удобен для небольших проектов, однако при росте приложения он быстро становится ограничивающим. Основная проблема плоской структуры — отсутствие логического группирования ключей.
i18next поддерживает вложенные объекты, позволяя организовывать переводы по смысловым блокам:
{
"auth": {
"login": "Войти",
"logout": "Выйти",
"register": "Регистрация"
},
"profile": {
"title": "Профиль пользователя",
"edit": "Редактировать профиль"
}
}
При обращении к таким ключам используется точечная нотация:
i18next.t('auth.login');
i18next.t('profile.title');
Вложенная структура снижает когнитивную нагрузку и упрощает масштабирование словаря.
При увеличении проекта один файл переводов перестаёт быть удобным. Пространства имён позволяют разделить переводы по модулям приложения.
Типичная структура каталогов:
locales/
ru/
common.json
auth.json
dashboard.json
en/
common.json
auth.json
dashboard.json
Пример auth.json:
{
"login": "Войти",
"logout": "Выйти"
}
Подключение пространства имён:
i18next.init({
lng: 'ru',
ns: ['common', 'auth'],
defaultNS: 'common',
resources: {
ru: {
common: require('./locales/ru/common.json'),
auth: require('./locales/ru/auth.json')
}
}
});
Использование ключей с указанием namespace:
i18next.t('auth:login');
Такой подход обеспечивает модульность и снижает риск конфликтов ключей.
Файлы переводов поддерживают динамические параметры. Это позволяет формировать строки с переменными значениями:
{
"greeting": "Привет, {{name}}",
"messages": "У вас {{count}} сообщений"
}
Использование:
i18next.t('greeting', { name: 'Алексей' });
i18next.t('messages', { count: 5 });
Интерполяция позволяет полностью исключить конкатенацию строк в коде и централизовать форматирование текста.
Одним из ключевых аспектов файлов переводов является поддержка множественных форм:
{
"apple_one": "Яблоко",
"apple_other": "Яблок",
"apple_few": "Яблока"
}
Использование:
i18next.t('apple', { count: 1 });
i18next.t('apple', { count: 3 });
i18next автоматически выбирает нужную форму в зависимости от языка и
переданного значения count.
Для языков с более сложной системой множественности могут использоваться дополнительные формы, определяемые правилами CLDR.
Контекст позволяет различать значения одной и той же строки в разных ситуациях:
{
"button_save": "Сохранить",
"button_save_context_admin": "Сохранить как администратор"
}
Использование:
i18next.t('button_save', { context: 'admin' });
Контекст особенно полезен в интерфейсах с повторяющимися действиями, где смысл текста зависит от роли пользователя или состояния системы.
Файлы переводов по умолчанию предназначены для текстового содержимого, однако иногда требуется вставка HTML-разметки:
{
"privacy": "Ознакомьтесь с <1>политикой конфиденциальности</1>"
}
В React или аналогичных библиотеках это обрабатывается через компоненты интерполяции, где числа обозначают вложенные элементы.
При этом важно учитывать настройку escapeValue,
предотвращающую XSS-уязвимости:
i18next.init({
interpolation: {
escapeValue: false
}
});
Организация ключей в файлах переводов влияет на поддерживаемость проекта. Используются различные стратегии:
{
"auth.login.title": "Вход в систему",
"auth.login.submit": "Отправить"
}
{
"auth": {
"login": {
"title": "Вход в систему",
"submit": "Отправить"
}
}
}
Иерархическая модель более предпочтительна при сложных интерфейсах, так как отражает структуру приложения.
Каждый язык хранится в отдельной директории. Это позволяет независимо развивать переводы:
locales/
en/
common.json
ru/
common.json
de/
common.json
При добавлении нового языка достаточно создать копию структуры и заполнить значения переводов, не изменяя код приложения.
В крупных приложениях файлы переводов часто загружаются по требованию:
i18next.init({
lng: 'ru',
backend: {
loadPath: '/locales/{{lng}}/{{ns}}.json'
}
});
Это позволяет уменьшить размер первоначальной загрузки и подгружать переводы только для активного языка и используемого модуля.
Файлы переводов могут быть неполными, поэтому задаётся резервный язык:
i18next.init({
fallbackLng: 'en'
});
Если ключ отсутствует в текущем языке, система автоматически обращается к fallback-файлу переводов.
При работе с несколькими языками критически важно поддерживать идентичную структуру файлов. Любое расхождение в ключах приводит к отсутствующим переводам.
Пример корректной синхронизации:
en/auth.json -> login, logout, register
ru/auth.json -> login, logout, register
de/auth.json -> login, logout, register
Несовпадение структуры:
en/auth.json -> login, logout
ru/auth.json -> login, register
Такая ситуация приводит к непредсказуемому поведению интерфейса.
JSON выбран как основной формат благодаря:
При необходимости допускается использование YAML или других форматов, однако они требуют дополнительного преобразования перед передачей в i18next.
Файлы переводов фактически выступают контрактом между интерфейсом и логикой локализации. Изменение ключа без обновления кода приводит к разрыву связи между слоями приложения.
По этой причине ключи обычно рассматриваются как стабильные идентификаторы, а изменения в текстах не затрагивают кодовую базу.