Использование context для вариативности

Механизм context в i18next предназначен для выбора варианта перевода в зависимости от дополнительного смыслового параметра, не связанного напрямую с языком. Это позволяет одной и той же ключевой строке иметь несколько форм, различающихся по гендеру, формальности, региональному стилю или любому другому семантическому признаку, определённому разработчиком.

Контекст работает поверх базовой системы ключей и интегрируется в процесс резолва перевода до применения fallback-цепочек.


Базовый принцип контекстной дифференциации

В i18next контекст реализуется через модификацию ключа перевода. Внутри ресурсов создаются вариации одного ключа с добавлением контекстного суффикса.

Наиболее распространённый формат:

{
  "friend": "Друг",
  "friend_male": "Друг",
  "friend_female": "Подруга"
}

Вызов перевода с контекстом:

i18next.t('friend', { context: 'female' });

Результатом будет:

Подруга

Если контекст не передан, используется базовый ключ friend.


Механика формирования ключей

Контекст добавляется к базовому ключу через разделитель, который настраивается параметром contextSeparator.

По умолчанию используется символ _.

Пример формирования итогового ключа:

friend + female → friend_female

Настройка:

i18next.init({
  contextSeparator: '_'
});

При изменении разделителя, например на .:

friend.female

Использование контекста в JSON-ресурсах

Структура ресурсов должна учитывать все возможные варианты контекста.

{
  "car": "Автомобиль",
  "car_new": "Новый автомобиль",
  "car_used": "Подержанный автомобиль"
}

Контекст передаётся как строка:

i18next.t('car', { context: 'new' });
i18next.t('car', { context: 'used' });

Это позволяет избегать дублирования ключей и сохранять логическую группировку переводов.


Контекст и грамматические категории

Наиболее частое применение context связано с языковыми особенностями:

Гендер

{
  "user": "Пользователь",
  "user_male": "Пользователь",
  "user_female": "Пользовательница"
}
i18next.t('user', { context: 'female' });

Формальность

{
  "greet_formal": "Здравствуйте",
  "greet_informal": "Привет"
}
i18next.t('greet', { context: 'formal' });

Региональные варианты

{
  "payment_card": "Банковская карта",
  "payment_card_eu": "Карта (ЕС формат)",
  "payment_card_us": "Карта (США формат)"
}
i18next.t('payment_card', { context: 'us' });

Порядок разрешения перевода с контекстом

При вызове t происходит последовательная проверка:

  1. Поиск ключа с контекстом

    key + contextSeparator + context
  2. Если не найден — поиск базового ключа

  3. Если включены fallback-языки — переход к ним

  4. Если ничего не найдено — возврат ключа или fallback-значения

Пример поведения:

i18next.t('button_save', { context: 'mobile' });

Поиск:

  • button_save_mobile
  • button_save

Контекст и множественные формы

Контекст может сочетаться с pluralization, но важно понимать приоритеты обработки.

Пример ресурсов:

{
  "message_one": "1 сообщение",
  "message_other": "{{count}} сообщений",
  "message_few_male": "{{count}} сообщения (муж.)",
  "message_few_female": "{{count}} сообщения (жен.)"
}

Вызов:

i18next.t('message', {
  count: 3,
  context: 'female'
});

Фактический ключ:

message_few_female

Контекст применяется после определения plural suffix.


Интерполяция и контекст

Контекст не заменяет интерполяцию, а дополняет её. Интерполяция остаётся механизмом вставки динамических значений.

{
  "invite_male": "Пригласил {{name}}",
  "invite_female": "Пригласила {{name}}"
}
i18next.t('invite', {
  context: 'female',
  name: 'Анна'
});

Результат:

Пригласила Анна

fallback при отсутствии контекстного ключа

Если контекстный вариант отсутствует, система автоматически переходит к базовому ключу.

{
  "status": "Активен"
}
i18next.t('status', { context: 'mobile' });

Результат:

Активен

Это поведение позволяет не дублировать переводы для каждого контекста, если различия несущественны.


Использование нескольких уровней контекста

Контекст может быть составным значением, если требуется более точная дифференциация.

{
  "button_save_primary_mobile": "Сохранить",
  "button_save_primary_desktop": "Сохранить изменения"
}
i18next.t('button_save', {
  context: 'primary_mobile'
});

Такой подход применяется при сложных UI-сценариях, где один параметр контекста недостаточен.


Настройка contextSeparator и его влияние

Параметр contextSeparator определяет, как формируется итоговый ключ.

i18next.init({
  contextSeparator: '::'
});

Ресурсы:

{
  "link": "Ссылка",
  "link::external": "Внешняя ссылка"
}

Вызов:

i18next.t('link', { context: 'external' });

Контекст и архитектура переводов

Использование context влияет на структуру словарей:

  • увеличивается количество ключей на один смысловой элемент
  • возрастает необходимость стандартизации контекстов
  • упрощается локализация сложных UI-состояний
  • снижается потребность в условной логике в коде интерфейса

Контекст фактически переносит часть логики выбора текста из приложения в слой локализации.


Контекст в связке с namespace

Контекст не ограничен пространством имён. Он применяется внутри namespace так же, как и к обычным ключам:

i18next.t('profile:role', { context: 'admin' });
{
  "role": "Роль",
  "role_admin": "Администратор",
  "role_user": "Пользователь"
}

Ограничения контекстного подхода

Контекст не предназначен для:

  • хранения динамических вычисляемых значений
  • замены условной логики сложных бизнес-сценариев
  • описания длинных структурированных фраз с множеством параметров

При чрезмерном использовании контекста словарь превращается в набор слабо различимых ключей, что усложняет поддержку.


Взаимодействие с fallbackLng

Контекст учитывается до применения языкового fallback. Это означает, что сначала ищется:

key + context

в текущем языке, затем в fallback-языках.

Пример цепочки:

  1. en: button_save_mobile
  2. en: button_save
  3. ru: button_save_mobile
  4. ru: button_save

Контекст как инструмент семантической декомпозиции

Контекст позволяет разложить одну языковую сущность на набор вариаций без изменения базовой структуры ключей. Это делает возможным моделирование:

  • грамматических различий
  • UI-состояний
  • пользовательских ролей
  • сценариев использования интерфейса

При этом сохраняется единый идентификатор смысловой группы, что упрощает поддержку и масштабирование переводов.