Стратегии при отсутствующих ключах

В i18next отсутствие ключа не является исключением исполнения, а обрабатывается как часть нормального потока разрешения строки перевода. Основная логика построена вокруг цепочки: поиск в текущем языке → поиск в fallback-языках → применение стратегий возврата значения.

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

Ключевой принцип: отсутствие перевода не ломает выполнение, а возвращает предсказуемое значение (ключ, fallback или пользовательское значение).


Базовая модель разрешения ключа

При вызове t('some.key') происходит последовательный поиск:

  1. Проверка активного языка (например, ru)
  2. Проверка namespace (например, common)
  3. Проверка fallback языков (fallbackLng)
  4. Применение стратегий возврата

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


Стратегия fallbackLng как основа устойчивости

Параметр fallbackLng определяет языки, которые используются при отсутствии перевода.

Типичный сценарий:

  • активный язык: ru
  • fallback: en

При отсутствии ключа в ru система автоматически обращается к en.

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

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

Многоуровневые цепочки fallback

Поддерживается каскадная стратегия:

fallbackLng: ['uk', 'ru', 'en']

Порядок строго детерминирован: uk → ru → en → ключ

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


Поведение при полном отсутствии ключа

Если ключ отсутствует во всех языках, применяется один из режимов:

  • возврат ключа ("some.missing.key")
  • возврат null
  • возврат пустой строки
  • пользовательское значение через defaultValue

Контролируется следующими настройками:

i18n.init({
  returnNull: false,
  returnEmptyString: false
});

returnNull

  • true → возвращается null
  • false → происходит дальнейшая обработка fallback или возврат ключа

returnEmptyString

Определяет, допускается ли пустая строка как валидный результат.


defaultValue как основной механизм защиты UI

defaultValue позволяет задать резервное значение на уровне вызова:

t('button.save', { defaultValue: 'Save' })

При отсутствии перевода возвращается Save.

Характеристика стратегии:

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

В сложных интерфейсах используется как слой безопасности поверх fallbackLng.


missingKeyHandler: централизованная обработка отсутствующих ключей

Механизм missingKeyHandler позволяет перехватывать события отсутствующих переводов.

i18n.init({
  missingKeyHandler: (lng, ns, key, fallbackValue) => {
    // логирование или отправка в систему мониторинга
  }
});

Типичные сценарии использования:

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

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


saveMissing и режим накопления ключей

Параметр saveMissing активирует автоматическую отправку отсутствующих ключей в backend:

i18n.init({
  saveMissing: true
});

При каждом отсутствии ключа происходит:

  1. фиксация ключа
  2. отправка в backend (если подключён адаптер)
  3. сохранение для будущей локализации

Это формирует динамический словарь недостающих переводов.


Роль namespace в стратегии отсутствующих ключей

i18next активно использует пространства имён (namespace), и отсутствие ключа может быть связано не с отсутствием перевода, а с отсутствием загрузки namespace.

Пример:

t('auth:login.title')

Если namespace auth не загружен:

  • система может попытаться подгрузить ресурс
  • либо вернуть fallback

Проверка доступности:

i18n.hasResourceBundle('ru', 'auth')

Динамическое добавление переводов

Отсутствие ключа может компенсироваться во время выполнения:

i18n.addResource('ru', 'common', 'button.save', 'Сохранить');

или пакетно:

i18n.addResourceBundle('ru', 'common', {
  button: {
    save: 'Сохранить'
  }
});

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


Стратегия различий между dev и production

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

Development

  • включён debug: true
  • отсутствующие ключи логируются
  • часто используется возврат ключа
i18n.init({
  debug: true
});

Production

  • отключено логирование
  • включён fallbackLng
  • активирован saveMissing (в некоторых системах)

Цель: минимизация визуальных артефактов и контроль качества переводов.


Порядок возврата значений (приоритет стратегий)

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

  1. Перевод в текущем языке
  2. Перевод в fallbackLng
  3. defaultValue
  4. returnEmptyString
  5. returnNull
  6. возврат ключа

Обработка вложенных ключей и разделителей

Стратегия отсутствующих ключей зависит от конфигурации разделителей:

i18n.init({
  keySeparator: '.',
  nsSeparator: ':'
});

При отключении разделителя (keySeparator: false) структура ключа становится плоской, что влияет на вероятность «ложного отсутствия» перевода.


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

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

  • plural
  • context
  • gender (через кастомные расширения)

Пример:

t('item', { count: 5 })

Если отсутствует форма item_plural, применяется:

  1. fallback plural rule
  2. базовый ключ
  3. fallbackLng

Интерполяция и частично отсутствующие значения

Даже при наличии ключа возможна неполнота данных:

t('welcome', { name: undefined })

Стратегии обработки:

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

Настройка:

interpolation: {
  skipOnVariables: false
}

Режим возврата объектов и отсутствующие поля

При returnObjects: true:

t('form', { returnObjects: true })

Если часть структуры отсутствует:

  • возвращается частичный объект
  • недостающие поля не создаются автоматически
  • fallback применяется только на уровне ключей

Практика безопасного UI при отсутствующих переводах

В системах с высокой динамикой данных применяется комбинация стратегий:

  • fallbackLng как основной слой
  • defaultValue для критичных элементов интерфейса
  • missingKeyHandler для мониторинга
  • saveMissing для накопления недостающих ключей
  • debug в среде разработки

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


Особенности поведения при ленивой загрузке ресурсов

При использовании backend-подгрузки:

  • ключ может считаться отсутствующим до завершения загрузки namespace
  • повторный вызов t() после загрузки может вернуть корректное значение
  • важно различать «реально отсутствующий ключ» и «ещё не загруженный ресурс»

Управление ресурсами во время выполнения

Контроль состояния переводов:

i18n.hasResourceBundle(lng, ns)
i18n.getResourceBundle(lng, ns)

Позволяет реализовывать стратегию:

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

Итоговая модель стратегий отсутствующих ключей

Система обработки отсутствующих переводов в i18next строится как многоуровневый конвейер:

  • языковая иерархия fallback
  • локальные значения через defaultValue
  • централизованное логирование missing-key событий
  • динамическое добавление ресурсов
  • настройка возврата null/пустых значений
  • разделение поведения между средами выполнения

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