В i18next одновременно применяются два механизма трансформации ключа перевода: контекст (context) и плюрализация (pluralization). Оба механизма влияют на итоговый ключ, по которому выполняется поиск строки в ресурсах, но порядок их применения строго определён и критичен для корректной структуры словарей.
При вызове перевода вида:
t('message', { count: 3, context: 'male' })
формируется цепочка разрешения ключа, где сначала учитывается контекст, затем число.
i18next строит ключ в несколько этапов:
messagemessage_malemessage_male_plural
(или message_male_one, message_male_other в
зависимости от языка)Итоговая последовательность поиска:
message_male_few (для языков с несколькими
формами)message_male_pluralmessage_male_othermessage_female_pluralmessage_pluralmessageФактический набор форм зависит от локали и настроек plural rules.
Комбинация context + plural требует предсказуемой структуры словаря. Обычно применяется схема:
{
"message": "сообщение",
"message_male": "сообщение для мужчины",
"message_female": "сообщение для женщины",
"message_one": "одно сообщение",
"message_other": "{{count}} сообщений",
"message_male_one": "одно сообщение для мужчины",
"message_male_other": "{{count}} сообщений для мужчины",
"message_female_one": "одно сообщение для женщины",
"message_female_other": "{{count}} сообщений для женщины"
}
Контекст добавляется первым суффиксом, plural — вторым.
import i18n from 'i18next';
i18n.init({
resources: {
ru: {
translation: {
message: "сообщение",
message_male_one: "одно сообщение для мужчины",
message_male_other: "{{count}} сообщений для мужчины",
message_female_one: "одно сообщение для женщины",
message_female_other: "{{count}} сообщений для женщины"
}
}
},
lng: 'ru',
fallbackLng: 'ru',
interpolation: {
escapeValue: false
}
});
i18n.t('message', { count: 1, context: 'male' });
// одно сообщение для мужчины
i18n.t('message', { count: 5, context: 'male' });
// 5 сообщений для мужчины
Если контекст отсутствует, используется базовая форма plural:
i18n.t('message', { count: 2 });
// 2 сообщений
Контекст всегда применяется до плюрализации. Это означает, что логически формируется «подключаемая подгруппа» переводов, внутри которой уже применяется языковая грамматика числа.
Схема поиска ключа:
baseKey
→ baseKey + '_' + context
→ baseKey + '_' + context + '_' + pluralForm
Такой порядок исключает пересечения между контекстами и формами множественного числа.
Если отсутствует ключ, включающий и context, и plural, выполняется деградация поиска:
message_male_othermessage_malemessage_othermessageПример:
i18n.t('message', { count: 3, context: 'female' });
Если отсутствует message_female_other, но существует
message_other, будет использована fallback-форма без
контекста.
По умолчанию i18next использует _ как разделитель.
Поведение регулируется настройкой:
i18n.init({
contextSeparator: '#'
});
Тогда структура ключей меняется:
{
"message#male_one": "одно сообщение для мужчины",
"message#male_other": "{{count}} сообщений для мужчины"
}
Это важно при интеграции с существующими системами локализации, где
_ уже используется в ключах.
Plural формы определяются языком и могут включать более двух категорий. Например:
В языках с расширенной системой множественного числа структура расширяется автоматически:
{
"car_male_one": "1 машина для мужчины",
"car_male_few": "{{count}} машины для мужчины",
"car_male_many": "{{count}} машин для мужчины",
"car_male_other": "{{count}} машин для мужчины"
}
Вызов:
i18n.t('car', { count: 7, context: 'male' });
Интерполяция применяется после выбора финального ключа.
{
"item_female_other": "{{user}} имеет {{count}} элементов"
}
i18n.t('item', {
context: 'female',
count: 3,
user: 'Анна'
});
Результат:
Анна имеет 3 элементов
Если count не передан, plural механизм не активируется,
даже при наличии plural-ключей.
i18n.t('message', { context: 'male' });
Поиск ограничивается:
message_malemessagePlural-формы игнорируются полностью.
Контекст не ограничивается гендером. Он используется как семантический переключатель:
{
"notification_email_one": "1 письмо",
"notification_email_other": "{{count}} писем",
"notification_push_one": "1 уведомление",
"notification_push_other": "{{count}} уведомлений"
}
i18n.t('notification', { context: 'email', count: 2 });
Контекст формирует отдельную ветку, внутри которой применяется plural.
i18next поддерживает один context, но на практике реализуется расширение через составные ключи:
{
"message_male_admin_one": "одно сообщение администратору",
"message_male_admin_other": "{{count}} сообщений администратору"
}
i18n.t('message', {
context: 'male_admin',
count: 4
});
Фактически context становится строкой-композицией,
увеличивая количество возможных ветвлений.
При одновременном наличии нескольких вариантов применяется следующий приоритет:
key + context + pluralkey + contextkey + pluralkeyЭто гарантирует предсказуемое поведение даже при неполной локализации.
При масштабировании словарей возникает необходимость строгого разделения:
Рекомендуемая структура:
{
"order": {
"male": {
"one": "1 заказ",
"other": "{{count}} заказов"
},
"female": {
"one": "1 заказ",
"other": "{{count}} заказов"
}
}
}
Однако при использовании flat-структуры i18next всё равно корректно разрешает ключи через суффиксы.
При отсутствии ключа в текущей локали выполняется переход в fallback-язык с сохранением всей цепочки:
message_male_one → fallback message_male_one → fallback message_one → message
Контекст и plural не теряются в процессе fallback-поиска, они сохраняются как часть ключа.
В редких случаях pluralSuffix может конфликтовать с contextSeparator. При нестандартных конфигурациях важно учитывать:
Формально:
key + contextSeparator + context + pluralSuffix
При включённом returnObjects возможно хранение вложенных
структур, где context и plural формируют дерево:
{
"message": {
"male": {
"one": "..."
}
}
}
В этом случае механизм ключей заменяется доступом к объекту, но логика context + plural сохраняется на уровне структуры.