Fallback языки и цепочки

В системе i18next обработка отсутствующих переводов основана на механизме цепочек резервных языков (fallback languages). При обращении к ключу перевода библиотека последовательно проходит по заранее заданному списку языков, пока не найдёт первое подходящее значение. Такой подход позволяет поддерживать частичную локализацию без необходимости полного покрытия всех языков.


Базовый принцип цепочки разрешения языка

При вызове перевода учитывается текущий язык (lng). Если ключ отсутствует, выполняется переход к следующему языку из fallback-цепочки, заданной через fallbackLng.

Типичный порядок разрешения:

  1. Текущий язык (lng)
  2. Языки из fallbackLng в заданном порядке
  3. Резервный язык по умолчанию (часто dev или en)
  4. Пустой результат или сам ключ (в зависимости от настроек)

Конфигурация fallbackLng

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

import i18n from 'i18next';

i18n.init({
  lng: 'ru',
  fallbackLng: 'en',
  resources: {
    en: {
      translation: {
        title: "Title"
      }
    }
  }
});

При отсутствии ключа в ru поиск продолжается в en.


Цепочки fallback-языков

Fallback может быть задан как массив, формируя явную цепочку приоритетов:

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

Механизм обработки:

  • сначала проверяется украинский (uk)
  • затем русский (ru)
  • затем английский (en)

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


Объектная конфигурация fallbackLng

Поддерживается настройка fallback на уровне отдельных языков:

i18n.init({
  lng: 'de-CH',
  fallbackLng: {
    'de-CH': ['de-DE', 'de', 'en'],
    'de': ['en'],
    'default': ['en']
  }
});

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


Fallback для языковых регионов

i18next автоматически учитывает языковые коды с регионами:

  • en-US
  • en-GB
  • pt-BR
  • pt-PT

Если перевод для en-US отсутствует, возможна деградация к en, если включена соответствующая логика fallback:

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

Поведение зависит от настроек load и nonExplicitSupportedLngs.


Параметр load и влияние на fallback

Параметр load определяет, как интерпретируются языковые коды:

  • all — загрузка всех вариантов
  • currentOnly — только точный язык
  • languageOnly — игнорирование регионов
i18n.init({
  load: 'languageOnly',
  fallbackLng: 'en'
});

При languageOnly en-US автоматически сводится к en, что уменьшает количество уровней fallback.


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

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

  • возврат ключа
  • возврат null
  • возврат пустой строки
i18n.init({
  returnNull: false,
  returnEmptyString: false
});

Комбинация этих параметров влияет на итоговое поведение цепочки fallback.


Fallback на уровне namespace

i18next поддерживает namespaces, и fallback может учитывать структуру ресурсов:

i18n.init({
  ns: ['common', 'home'],
  defaultNS: 'common',
  fallbackLng: ['en']
});

Если ключ отсутствует в текущем namespace, поиск продолжается:

  1. текущий язык + текущий namespace
  2. fallback-язык + текущий namespace
  3. fallback-язык + default namespace

Приоритеты языков и namespaces

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

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

Пример структуры ресурсов:

resources: {
  en: {
    common: { ok: "OK" },
    home: { title: "Home" }
  },
  ru: {
    common: { ok: "ОК" }
  }
}

При запросе home.title в ru:

  • ru/home/title → отсутствует
  • en/home/title → найдено

Динамическое поведение fallback

Fallback-цепочка может изменяться во время выполнения:

i18n.changeLanguage('fr');
i18n.options.fallbackLng = ['fr', 'en'];

Такой подход используется в сценариях:

  • пользовательские языковые настройки
  • A/B тестирование переводов
  • постепенная миграция локализаций

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

При использовании вложенных структур:

resources: {
  en: {
    translation: {
      user: {
        profile: {
          title: "Profile"
        }
      }
    }
  }
}

Fallback применяется на уровне полного ключа. Частичное совпадение не считается успешным результатом. Если user.profile.title отсутствует, происходит переход к следующему языку целиком.


Fallback и интерполяция

Fallback влияет только на выбор перевода, но не на обработку интерполяции:

{
  greeting: "Hello {{name}}"
}

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


Fallback и контекстные формы

Контекстные ключи учитываются в цепочке так же, как обычные:

  • key
  • key_male
  • key_female

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


Поведение с multiple fallback chains

В сложных системах возможны вложенные цепочки:

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

При этом каждая ветка проверяется полностью до перехода к следующей. Это создаёт линейную деградацию качества перевода:

  • локальный язык
  • регионально близкий язык
  • универсальный язык

Оптимизация fallback-цепочек

Эффективность fallback зависит от:

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

Слишком длинные цепочки увеличивают количество проверок при каждом обращении к переводу. Поэтому часто используются компактные конфигурации:

fallbackLng: ['en']

или ограниченные региональные цепочки:

fallbackLng: ['de', 'en']

Влияние detection plugin на fallback

При использовании i18next-browser-languagedetector итоговый язык может определяться автоматически, после чего применяется fallback:

  • cookie
  • localStorage
  • navigator.language
  • query string

После определения lng активируется стандартная цепочка fallbackLng, что создаёт многоуровневую систему выбора локали.


Кэширование и fallback

При использовании backend-лоадеров переводы могут кэшироваться. В этом случае fallback происходит:

  • либо на уровне запроса ресурсов
  • либо на уровне уже загруженных данных

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


Ошибки и диагностика fallback

Для анализа fallback-цепочек используется debug-режим:

i18n.init({
  debug: true
});

В логах фиксируются:

  • отсутствующие ключи
  • язык, в который произошёл fallback
  • итоговый источник строки

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


Поведение при отключённом fallback

При отключении fallback:

i18n.init({
  fallbackLng: false
});

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