Мужской и женский род

В системах интернационализации на базе JavaScript поддержка грамматического рода становится критически важной при работе с языками, где формы слов зависят от пола субъекта. В i18next этот механизм реализуется через контекст (context) и расширенные правила выбора ключей перевода, позволяющие разделять строки по признаку мужского и женского рода без дублирования логики в коде приложения.

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


Контекст как основа работы с родом

В i18next механизм контекста реализуется через добавление суффикса к ключу перевода. По умолчанию используется разделитель _, формируя составные ключи:

  • user_male
  • user_female

При этом логический ключ остаётся единым — user, а различие определяется параметром context.

Базовая структура ресурсов

{
  "user_male": "Пользователь вошёл в систему",
  "user_female": "Пользовательница вошла в систему"
}

Использование в коде

i18next.t('user', { context: 'male' });
// "Пользователь вошёл в систему"

i18next.t('user', { context: 'female' });
// "Пользовательница вошла в систему"

Контекст работает как механизм подстановки варианта перевода без изменения базового ключа.


Определение рода через параметры данных

В реальных приложениях род часто определяется на основе данных пользователя. Обычно в объект пользователя добавляется поле gender, которое затем передаётся в функцию перевода.

Пример структуры пользователя

const user = {
  name: 'Анна',
  gender: 'female'
};

Использование в шаблоне

i18next.t('welcome', { context: user.gender });

Ресурсы перевода

{
  "welcome_male": "Добро пожаловать, пользователь",
  "welcome_female": "Добро пожаловать, пользовательница"
}

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


Контекст и сложные ключи

В сложных системах переводов часто требуется комбинировать несколько параметров: род, число, состояние объекта. i18next поддерживает многоуровневую структуру ключей.

Пример комбинированных ключей

{
  "friend_male_singular": "Друг онлайн",
  "friend_female_singular": "Подруга онлайн",
  "friend_male_plural": "Друзья онлайн",
  "friend_female_plural": "Подруги онлайн"
}

Использование с параметрами

i18next.t('friend', {
  context: user.gender,
  count: 1
});

Однако базовый механизм i18next не автоматически объединяет context и count в единый ключ без дополнительной настройки. Поэтому часто используется ручное построение ключа или middleware-логика.


Работа с множественными формами и родом

В языках с развитой морфологией, таких как русский, необходимо учитывать одновременно два фактора:

  • число (единственное / множественное)
  • род (мужской / женский)

Ресурсы с разбиением по числу и роду

{
  "message_male_one": "1 новый друг",
  "message_male_other": "{{count}} новых друзей",
  "message_female_one": "1 новая подруга",
  "message_female_other": "{{count}} новых подруг"
}

Логика выбора ключа

const key = `message_${user.gender}`;

i18next.t(key, { count: 5 });

Такой подход сохраняет прозрачность структуры и упрощает масштабирование переводов при росте проекта.


Контекстный разделитель и конфигурация i18next

По умолчанию i18next использует _ как разделитель контекста:

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

Это означает, что ключ profile_male интерпретируется как:

  • базовый ключ: profile
  • контекст: male

Изменение разделителя

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

В этом случае ресурсы должны быть переименованы:

{
  "profile-male": "Профиль пользователя",
  "profile-female": "Профиль пользовательницы"
}

Передача контекста через параметры перевода

Контекст в i18next передаётся через объект опций:

t('key', { context: 'male' });

Дополнительно можно комбинировать с интерполяцией:

t('greeting', {
  context: user.gender,
  name: user.name
});

Пример ресурса

{
  "greeting_male": "Здравствуйте, {{name}}",
  "greeting_female": "Здравствуйте, {{name}}"
}

Интерполяция остаётся общей, а различие создаётся только по контексту.


Определение пола на уровне приложения

В реальных архитектурах значение gender часто хранится:

  • в профиле пользователя
  • в JWT токене
  • в состоянии Redux / Zustand / Pinia
  • в ответе API

Пример интеграции с API

async function loadUser() {
  const response = await fetch('/api/user');
  const user = await response.json();

  i18next.changeLanguage(user.language);

  return user;
}

Использование:

const user = await loadUser();

i18next.t('dashboard', {
  context: user.gender
});

Фолбэк при отсутствии контекста

Если контекстный ключ отсутствует, i18next использует базовый ключ без суффикса:

{
  "notification": "Уведомление",
  "notification_male": "Уведомление для мужчины"
}

При отсутствии notification_female система вернёт:

  • либо notification
  • либо ключ из fallback языка

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


Обработка рода без дублирования ключей

Дублирование ключей быстро приводит к росту словаря переводов. Для уменьшения избыточности применяются стратегии:

1. Обобщённые фразы

{
  "user_online": "Пользователь онлайн"
}

При этом род игнорируется, если текст нейтрален.

2. Использование интерполяции вместо контекста

{
  "user_online": "{{name}} онлайн"
}

В этом случае род влияет только на имя или отдельные слова.

3. Внешняя функция формирования ключа

function getGenderKey(base, gender) {
  return `${base}_${gender}`;
}

i18next.t(getGenderKey('profile', user.gender));

Сложные случаи морфологии

В некоторых ситуациях род влияет не только на отдельное слово, но и на структуру предложения:

{
  "invite_male": "{{name}} пригласил вас",
  "invite_female": "{{name}} пригласила вас"
}
i18next.t('invite', {
  context: user.gender,
  name: user.name
});

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


Ограничения и архитектурные особенности

Контекстный механизм i18next не является полноценной грамматической системой. Он опирается на статическое сопоставление ключей, поэтому:

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

По этой причине в крупных системах часто комбинируются:

  • context i18next
  • ICU MessageFormat (через плагины)
  • кастомные функции склонения

Комбинация с ICU и расширенными форматами

При использовании ICU-подхода род может выражаться через выбор:

{
  "invite": "{gender, select, male {Он пригласил вас} female {Она пригласила вас} other {Пользователь пригласил вас}}"
}

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


Практика организации ресурсов

При проектировании структуры переводов с учётом рода часто используется следующая организация:

locales/
  ru/
    common.json
    user.json
    notifications.json

Пример user.json

{
  "profile_male": "Профиль пользователя",
  "profile_female": "Профиль пользовательницы",
  "status_male": "Активен",
  "status_female": "Активна"
}

Такое разделение уменьшает конфликт ключей и облегчает масштабирование.


Особенности поддержки в приложениях с SSR и SPA

В серверных и клиентских рендерах важно синхронизировать контекст:

  • на сервере определяется язык и профиль пользователя
  • на клиенте контекст должен быть восстановлен
i18next.init({
  lng: user.language,
  resources
});

Контекст передаётся в момент рендеринга:

t('welcome', { context: user.gender });

Несогласованность между сервером и клиентом может приводить к различиям в отображении текста.


Типовые ошибки при работе с родом

  • отсутствие fallback-ключей для одного из контекстов
  • смешивание логики пола и бизнес-логики в ресурсах
  • чрезмерное разбиение переводов
  • использование контекста там, где достаточно интерполяции
  • игнорирование комбинированных форм (род + число)

Такие ошибки приводят к росту сложности словаря и ухудшению поддерживаемости локализации.