Поддержка консистентности

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

Иерархическая структура ключей

i18next поддерживает вложенные структуры:

{
  "auth": {
    "login": {
      "title": "Вход",
      "button": "Войти"
    }
  }
}

Доступ к таким ключам осуществляется через точечную нотацию:

t('auth.login.title');

Консистентность достигается за счёт соблюдения единого уровня вложенности. Смешивание плоских и вложенных ключей внутри одного проекта приводит к потере предсказуемости и усложняет масштабирование.

Рекомендуемый подход — фиксированная схема:

  • уровень модуля (auth, profile, cart)
  • уровень экрана или сущности (login, settings)
  • уровень элемента интерфейса (title, button, placeholder)

Единый стиль именования ключей

Стабильность системы переводов напрямую зависит от выбранного стиля именования:

  • camelCase
  • snake_case
  • dot.notation

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

t('userProfile.title');
t('user_profile.title');

Такая ситуация нарушает консистентность и увеличивает риск несоответствия переводов между языками.


Консистентность интерполяции

i18next использует интерполяцию для динамических значений:

t('greeting', { name: 'Alex' });

и ресурс:

{
  "greeting": "Привет, {{name}}"
}

Единые правила именования переменных

Переменные интерполяции должны быть:

  • предсказуемыми (name, count, date)
  • повторно используемыми во всех переводах
  • независимыми от языка

Нарушение консистентности интерполяции проявляется, когда одна и та же сущность называется по-разному:

"welcome_user": "Hello {{username}}"
"farewell_user": "Bye {{name}}"

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


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

Механизм pluralization в i18next требует строгого соблюдения структуры ключей:

{
  "item": "1 предмет",
  "item_plural": "{{count}} предметов"
}

или через ICU-подобный синтаксис:

{
  "item": "{{count}} item",
  "item_plural": "{{count}} items"
}

Стабильность правил множественности

Консистентность достигается за счёт:

  • одинакового использования суффиксов (_plural, _singular)
  • единообразной логики count
  • отсутствия ручных ветвлений в коде

Пример нарушения:

t('item', { count: 2 }) + 's';

Такой подход ломает локализацию и создаёт зависимость от конкретного языка.


Консистентность fallback-стратегий

i18next поддерживает fallback-языки, что критично для устойчивости интерфейса:

i18n.init({
  fallbackLng: 'en'
});

Единая стратегия резервирования

Консистентность обеспечивается при соблюдении следующих правил:

  • одинаковый fallback для всех модулей
  • отсутствие локальных переопределений fallback
  • синхронность языковых цепочек (ru → en, а не разрозненные цепочки)

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


Консистентность namespace-структуры

Namespaces позволяют разделять переводные ресурсы:

i18n.init({
  ns: ['common', 'auth', 'dashboard']
});

Единый принцип разбиения

Консистентная структура namespaces должна:

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

Типичная ошибка — размещение одних и тех же ключей в разных namespaces:

common: { save: "Save" }
auth: { save: "Save" }

Это создаёт конфликт смыслов и усложняет поддержку.


Консистентность загрузки ресурсов

i18next поддерживает асинхронную загрузку переводов через backend-плагины.

Синхронизация состояния ресурсов

Критично поддерживать единый механизм загрузки:

  • одинаковый backend для всех языков
  • одинаковые правила кеширования
  • единый формат файлов (JSON, YAML)

Пример конфигурации:

i18n.init({
  backend: {
    loadPath: '/locales/{{lng}}/{{ns}}.json'
  }
});

Нарушение консистентности возникает при смешении источников:

  • часть переводов из API
  • часть из статических файлов
  • часть из локального кеша

Консистентность кэширования переводов

Кэширование напрямую влияет на актуальность интерфейса.

Согласованные правила обновления

Для предотвращения расхождений:

  • единый TTL для всех языков
  • синхронная инвалидация кэша при обновлении ресурсов
  • отсутствие локальных обходов кэширования в отдельных модулях

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


Консистентность форматирования данных

i18next часто используется вместе с форматированием чисел, дат и валют:

t('price', { value: 1200, formatParams: { value: { currency: 'USD' } } });

Единые правила форматирования

Консистентность достигается через:

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

Нарушение:

'Price: $' + price;

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


Консистентность SSR и гидрации

В приложениях с серверным рендерингом важно синхронизировать состояние i18next между сервером и клиентом.

Единый контекст перевода

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

  • одинаковый язык
  • одинаковые загруженные namespaces
  • одинаковую версию ресурсов

Типичная проблема — рассинхронизация:

  • сервер отдал HTML на русском
  • клиент инициализировался на английском

Это приводит к миганию интерфейса и несоответствию текста.


Консистентность при динамическом переключении языков

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

Синхронизация всех слоёв

После смены языка необходимо, чтобы:

  • обновились все namespaces
  • пересчитались интерполяции
  • обновились форматтеры
  • пересобрались кэшированные значения

Нарушение возникает, когда часть компонентов реагирует на смену языка, а часть — нет.


Консистентность ключей в кодовой базе

Поддержание структуры ключей требует строгой дисциплины.

Избежание дублирования

Повторяющиеся ключи в разных частях проекта приводят к конфликтам:

t('button.save')
t('form.save')

При одинаковом значении это допустимо, но при расхождении переводов возникает неоднозначность.

Контракт между кодом и переводами

Ключи рассматриваются как API:

  • изменение ключа = breaking change
  • удаление ключа = потенциальная ошибка
  • переименование ключа = требует миграции всех языков

Консистентность валидации переводов

Для предотвращения рассинхронизации между языками применяется контроль структуры переводов.

Сравнение схем

Все языковые файлы должны иметь:

  • одинаковую структуру ключей
  • одинаковые namespaces
  • одинаковую глубину вложенности

Отсутствие ключа в одном языке автоматически приводит к fallback-использованию, что визуально ломает интерфейс.


Консистентность при масштабировании проекта

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

Архитектурные принципы

Поддержание целостности достигается через:

  • разделение переводов по доменам
  • централизованное управление ключами
  • запрет локальных “самодельных” строк в UI

Любая строка, не проходящая через i18next, становится источником несогласованности интерфейса.


Консистентность между библиотеками и слоями приложения

i18next часто используется вместе с UI-фреймворками и бизнес-логикой.

Единая точка доступа к переводам

Переводы должны запрашиваться только через один слой:

  • либо через хук (useTranslation)
  • либо через сервис i18n
  • либо через обёртку

Смешение подходов:

i18n.t('key')
useTranslation().t('key')

допустимо только при строгой синхронизации контекста, иначе возникает рассогласование состояния.


Консистентность обновления языковых ресурсов

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

Атомарность обновлений

Обновление должно быть:

  • целостным (все ключи языка обновляются одновременно)
  • версионированным
  • обратимо контролируемым через fallback

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