В проектах, использующих i18next, основная сложность возникает не в технической интеграции библиотеки, а в поддержании согласованности переводов между разработчиками, продуктовой логикой и файлами локализации. Поэтому ключевым соглашением становится строгая структура именования ключей.
На практике применяются два распространённых подхода:
Составные ключи через точку
{
"auth.login.title": "Вход",
"auth.login.button": "Войти"
}Вложенная структура объектов
{
"auth": {
"login": {
"title": "Вход",
"button": "Войти"
}
}
}Оба варианта технически эквивалентны в i18next, однако в командной разработке важно зафиксировать один стиль. Смешивание подходов приводит к дублированию ключей и усложнению рефакторинга.
Чаще выбирается точечная нотация, поскольку она лучше масштабируется при автоматической генерации и поиске ключей в кодовой базе.
Единообразие именования переводов снижает когнитивную нагрузку при работе с локализациями. В рамках командных соглашений обычно фиксируются следующие правила:
camelCase или snake_case, но
не обоих одновременноПримеры допустимых ключей:
user.profile.title
cart.item.removeButton
order.status.pending
Недопустимые варианты:
clickRemoveItemNow
button_for_deleting_item_from_cart
removeItemFromCartWhenUserClicks
Ключи должны описывать сущность и назначение, а не действие или сценарий.
i18next активно использует концепцию пространств имён (namespaces), которая позволяет разделять переводы по модулям приложения.
Типовая структура:
locales/
en/
common.json
auth.json
cart.json
ru/
common.json
auth.json
cart.json
Каждый namespace соответствует функциональному блоку:
common — общие элементы интерфейсаauth — авторизация и регистрацияcart — корзина покупокprofile — пользовательские данныеВ коде это отражается явно:
i18next.t('login.title', { ns: 'auth' });
В командных соглашениях фиксируется правило: каждый новый
модуль обязан иметь собственный namespace, чтобы избежать
разрастания common.
Структура каталогов переводов должна быть предсказуемой и зеркальной для всех языков.
Рекомендуемая организация:
locales/
en/
auth.json
cart.json
ru/
auth.json
cart.json
de/
auth.json
cart.json
Основные правила:
Нарушение симметрии приводит к ошибкам fallback-механизма и усложняет автоматические проверки покрытия переводов.
i18next поддерживает интерполяцию значений через синтаксис:
t('welcome', { name: 'Alex' });
И соответствующий перевод:
{
"welcome": "Добро пожаловать, {{name}}"
}
В командных соглашениях фиксируются следующие правила:
{{variable}}, без альтернативных
синтаксисовНедопустимо:
{
"price": "Цена: {{price * taxRate}}"
}
Корректный подход:
const total = price * taxRate;
t('price', { value: total });
i18next поддерживает plural rules в зависимости от языка:
{
"item": "1 предмет",
"item_other": "{{count}} предметов"
}
В коде:
t('item', { count: 5 });
Командные стандарты обычно требуют:
count как единственного
параметраДля языков со сложной морфологией (русский, польский) допускается расширенная форма:
{
"item_one": "{{count}} предмет",
"item_few": "{{count}} предмета",
"item_many": "{{count}} предметов"
}
Контекст позволяет изменять перевод в зависимости от состояния:
t('button', { context: 'save' });
t('button', { context: 'delete' });
Файл перевода:
{
"button_save": "Сохранить",
"button_delete": "Удалить"
}
Соглашения команды обычно ограничивают использование context:
Контекст не должен заменять namespace.
В современных проектах часто применяется ICU MessageFormat через
i18next-icu.
Пример:
{
"cart": "{count, plural, one {# товар} few {# товара} other {# товаров}}"
}
Соглашения:
i18next не занимается форматированием напрямую, но интегрируется с
Intl.
Соглашения команды:
Пример неправильного подхода:
{
"date": "Сегодня 12.05.2026"
}
Правильный вариант:
{
"date": "Сегодня {{date}}"
}
И форматирование в коде:
const formatted = new Intl.DateTimeFormat('ru-RU').format(date);
t('date', { date: formatted });
Fallback является важной частью архитектуры локализации.
Типичная конфигурация:
i18next.init({
fallbackLng: 'en',
fallbackNS: 'common'
});
Командные правила:
Для поддержания консистентности переводов применяются автоматические проверки:
Пример правила линтера:
rules: {
'i18n/no-missing-keys': 'error',
'i18n/no-unused-keys': 'warn'
}
Повторное использование переводов допускается только при строгом совпадении контекста.
Запрещается:
Допускается:
commonКомандная модель работы с i18next требует четкого разграничения:
Ключи рассматриваются как стабильный API, который не должен меняться без миграции.
В крупных системах вводится версионирование локалей:
Пример стратегии:
v1/auth.json
v2/auth.json
или через миграции ключей:
renameKey('auth.login.title', 'auth.signIn.title');
Для предотвращения проблем UI применяются ограничения:
Допускается:
{
"warning": "Действие необратимо"
}
Недопустимо:
{
"warning": "<b>Внимание:</b> действие необратимо, нажмите OK"
}