Кодовая база, использующая i18next, опирается на разделение переводов, модульность и предсказуемую структуру загрузки ресурсов. Основная цель — изолировать текстовые ресурсы от бизнес-логики и обеспечить масштабируемость при росте количества языков и функциональных модулей.
Ключевые принципы:
Базовая организация ресурсов строится вокруг языков и namespaces одновременно. Наиболее распространённая схема:
/locales
/en
common.json
auth.json
dashboard.json
/ru
common.json
auth.json
dashboard.json
/kk
common.json
auth.json
dashboard.json
Каждый файл представляет отдельный namespace, а язык — верхний уровень группировки.
Альтернативная структура для более крупных проектов:
/locales
/en
/common
header.json
footer.json
/auth
login.json
register.json
/ru
/common
header.json
footer.json
/auth
login.json
register.json
Такая структура облегчает распределение ответственности между командами и снижает вероятность конфликтов при изменениях.
Namespaces в i18next позволяют разделять переводы по функциональным блокам приложения. Каждый namespace соответствует доменной области.
Инициализация i18next с namespaces:
import i18n from 'i18next';
i18n.init({
lng: 'en',
fallbackLng: 'en',
ns: ['common', 'auth', 'dashboard'],
defaultNS: 'common',
resources: {}
});
Использование namespace в коде:
i18n.t('login.title', { ns: 'auth' });
Преимущества:
В архитектуре крупных приложений каждый модуль содержит собственные переводы рядом с кодом.
Пример структуры feature-based архитектуры:
/src
/features
/auth
login.js
auth.i18n.js
/locales
en.json
ru.json
/dashboard
dashboard.js
dashboard.i18n.js
/locales
en.json
ru.json
Подход позволяет:
Регистрация ресурсов:
import i18n from 'i18next';
import en from './locales/en.json';
import ru from './locales/ru.json';
i18n.addResourceBundle('en', 'auth', en);
i18n.addResourceBundle('ru', 'auth', ru);
Переводы обычно хранятся в JSON с вложенной структурой ключей.
Пример:
{
"login": {
"title": "Sign in",
"submit": "Login",
"error": {
"invalid": "Invalid credentials"
}
}
}
Рекомендации по структуре:
login_titleДля масштабируемых приложений используется загрузка переводов по запросу через backend.
Использование i18next-http-backend:
import i18n from 'i18next';
import HttpBackend from 'i18next-http-backend';
i18n
.use(HttpBackend)
.init({
lng: 'en',
fallbackLng: 'en',
backend: {
loadPath: '/locales/{{lng}}/{{ns}}.json'
}
});
Такая схема позволяет:
При использовании bundler’ов (Webpack, Vite, Rollup) переводы можно привязывать к динамическим импортам.
Пример:
async function loadAuthModule() {
const module = await import('./features/auth/auth.js');
await i18n.loadNamespaces('auth');
return module;
}
Логика:
Организация кодовой базы должна учитывать сценарии переключения языков без перезагрузки.
Основные элементы:
Пример смены языка:
i18n.changeLanguage('ru');
Структурно важно:
При активной разработке возникает необходимость синхронизации изменений между языками.
Практики версионирования:
Пример проверки:
const missingKeys = i18n.getMissingKeys('ru');
console.log(missingKeys);
Дополнительная практика — использование базового языка как источника истины:
en (source of truth)
ru (derived)
kk (derived)
Fallback-настройки определяют поведение при отсутствии перевода:
i18n.init({
fallbackLng: ['en', 'ru'],
fallbackNS: 'common'
});
Организационно это влияет на структуру:
common содержит универсальные
строкиКодовая база должна включать проверки консистентности переводов.
Типовые тесты:
Проверка наличия ключей:
import en from './locales/en/common.json';
import ru from './locales/ru/common.json';
function diffKeys(a, b) {
return Object.keys(a).filter(k => !b[k]);
}
console.log(diffKeys(en, ru));
Проверка использования ключей в коде:
/src
/app
i18n.js
/features
/auth
auth.service.js
auth.view.js
auth.i18n.js
/locales
en.json
ru.json
/dashboard
dashboard.controller.js
dashboard.view.js
/locales
en.json
ru.json
/shared
/components
/locales
common.en.json
common.ru.json
/locales
/en
common.json
/ru
common.json
Архитектура сочетает:
По мере увеличения приложения критически важным становится контроль структуры переводов:
Пример соглашения:
feature.section.element.state
auth.login.button.submit
dashboard.stats.chart.title
Такой формат обеспечивает предсказуемость и снижает когнитивную нагрузку при сопровождении системы локализации.