Структура ключей перевода в i18next определяет масштабируемость локализации, читаемость словарей и предсказуемость работы с языковыми ресурсами. При росте приложения неупорядоченные ключи приводят к дублированию строк, конфликтам имён и усложнению поддержки переводов.
Ключ перевода представляет собой идентификатор, который связывает код приложения с конкретной строкой в языковом ресурсе. В i18next он может быть как простым строковым ключом, так и вложенным путём в объекте JSON.
Плоская структура предполагает хранение всех ключей на одном уровне без вложенности.
Пример:
{
"welcome": "Добро пожаловать",
"logout": "Выйти",
"errorRequired": "Поле обязательно",
"errorInvalidEmail": "Некорректный email"
}
Такая организация проста на ранних этапах, но быстро теряет управляемость при увеличении количества переводов. Основная проблема — отсутствие контекста. Ключи начинают разрастаться в длинные и неочевидные идентификаторы.
Типичные признаки деградации плоской структуры:
homeTitle, homeButtonSave,
homeButtonCancelВложенные ключи являются предпочтительным способом организации в i18next. Они формируют иерархию смысловых блоков.
Пример:
{
"auth": {
"login": {
"title": "Вход",
"submit": "Войти"
},
"logout": "Выйти"
},
"errors": {
"required": "Поле обязательно",
"invalidEmail": "Некорректный email"
}
}
Доступ к таким ключам осуществляется через точечную нотацию:
i18next.t('auth.login.title');
i18next.t('errors.required');
Преимущества вложенной структуры:
Dot notation является способом адресации вложенных ключей через
строку с разделителями ..
Пример обращения:
t('profile.settings.security.password');
Соответствующая структура:
{
"profile": {
"settings": {
"security": {
"password": "Пароль"
}
}
}
}
Важно учитывать, что точечная нотация в i18next не требует ручного парсинга — библиотека интерпретирует строку как путь в объекте.
Сильная вложенность повышает выразительность, но чрезмерная глубина усложняет поддержку. Оптимальная глубина обычно ограничивается 3–4 уровнями.
Namespaces позволяют разделять переводы на логические файлы или области ответственности.
Пример конфигурации:
i18next.init({
ns: ['common', 'auth', 'profile', 'errors'],
defaultNS: 'common'
});
Структура файлов:
locales/
en/
common.json
auth.json
profile.json
errors.json
Пример использования:
t('login', { ns: 'auth' });
t('required', { ns: 'errors' });
Namespaces решают ключевые проблемы масштабирования:
Логическая организация ключей часто строится вокруг доменов приложения.
Типичные домены:
auth — авторизация и регистрацияuser — профиль пользователяdashboard — главная панельsettings — настройкиerrors — ошибки системыcommon — общие элементы интерфейсаПример:
{
"settings": {
"language": "Язык",
"theme": "Тема",
"notifications": "Уведомления"
}
}
Доменные ключи уменьшают когнитивную нагрузку при работе с переводами, так как структура отражает архитектуру приложения.
Стабильная система именования ключей критична для долгосрочной поддержки.
Распространённые подходы:
{
"invalidEmailFormat": "Некорректный email"
}
Используется в приложениях с JavaScript-ориентированной культурой кода.
{
"invalid_email_format": "Некорректный email"
}
Чаще встречается в системах с межъязыковой совместимостью.
{
"invalid-email-format": "Некорректный email"
}
Используется реже из-за неудобства обращения через dot notation.
На практике наиболее устойчивым считается camelCase внутри значений и вложенные структуры вместо длинных плоских ключей.
i18next поддерживает интерполяцию значений внутри переводов:
{
"welcomeUser": "Добро пожаловать, {{name}}"
}
t('welcomeUser', { name: 'Алексей' });
При проектировании ключей важно отделять структуру ключа от динамических данных. Ошибочная практика — включение параметров в ключ:
{
"welcome_alexey": "Добро пожаловать, Алексей"
}
Такая модель приводит к экспоненциальному росту ключей и разрушает систему локализации.
i18next поддерживает множественные формы через специальные суффиксы.
Пример:
{
"item_one": "1 элемент",
"item_few": "{{count}} элемента",
"item_many": "{{count}} элементов"
}
Использование:
t('item', { count: 5 });
В более структурированном варианте:
{
"cart": {
"item": {
"one": "1 товар",
"other": "{{count}} товаров"
}
}
}
t('cart.item', { count: 3 });
Вложенная структура упрощает сопровождение и уменьшает вероятность дублирования логики.
Контекст позволяет различать переводы в зависимости от ситуации.
Пример:
{
"button_save": "Сохранить",
"button_save_context_admin": "Сохранить (админ)"
}
i18next поддерживает context параметр:
t('button_save', { context: 'admin' });
Более чистая структура:
{
"button": {
"save": "Сохранить",
"save_admin": "Сохранить (админ)"
}
}
Контекст лучше отражать через вложенность, а не через длинные суффиксы ключей.
При масштабировании системы переводов возникает необходимость переиспользования строк.
Пример:
{
"common": {
"cancel": "Отмена",
"confirm": "Подтвердить"
},
"modal": {
"cancel": "Отмена",
"confirm": "Подтвердить"
}
}
Дублирование указывает на необходимость выделения общего слоя:
{
"common": {
"cancel": "Отмена",
"confirm": "Подтвердить"
},
"modal": {
"cancel": "{{common.cancel}}",
"confirm": "{{common.confirm}}"
}
}
Однако чрезмерная композиция усложняет зависимости между ключами, поэтому часто предпочтительнее прямое использование общего namespace:
t('cancel', { ns: 'common' });
При росте проекта структура ключей обычно эволюционирует в многоуровневую систему:
locales/
en/
common.json
auth.json
user.json
dashboard.json
errors.json
forms.json
Внутри каждого namespace применяется одинаковый принцип вложенности:
{
"form": {
"submit": "Отправить",
"reset": "Сбросить",
"validation": {
"required": "Обязательное поле",
"minLength": "Слишком короткое значение"
}
}
}
Единообразие структуры между namespaces снижает когнитивную нагрузку при работе с переводами.
Жёсткая привязка ключей к UI-элементам приводит к хрупкой системе:
{
"homePageTopBannerButtonBlue": "Нажать"
}
Такие ключи невозможно переиспользовать и сложно рефакторить.
Более устойчивая модель:
{
"banner": {
"primaryAction": "Нажать"
}
}
Ключи должны отражать смысл, а не расположение в интерфейсе.
Формы являются одной из наиболее сложных зон локализации.
Рекомендуемая структура:
{
"forms": {
"login": {
"email": {
"label": "Email",
"placeholder": "Введите email",
"error": {
"required": "Email обязателен",
"invalid": "Некорректный email"
}
},
"password": {
"label": "Пароль",
"error": {
"required": "Пароль обязателен"
}
}
}
}
}
Такая организация объединяет все элементы формы в единую семантическую область.
С увеличением числа переводов структура проходит несколько стадий:
Каждый следующий этап снижает хаос предыдущего и повышает предсказуемость системы локализации.