Определение текущего языка

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


i18next.language

Основное свойство для получения активного языка — i18next.language. Оно отражает текущий выбранный язык, используемый для получения переводов.

import i18next from "i18next";

console.log(i18next.language);

Значение этого свойства зависит от нескольких факторов:

  • языка, заданного при инициализации;
  • результата работы детектора языка;
  • последнего вызова changeLanguage.

Типичный формат значения:

  • en
  • ru
  • de
  • en-US
  • pt-BR

Важно учитывать, что language может содержать как базовый код языка, так и локализованную версию с регионом.


i18next.languages

Свойство i18next.languages содержит массив языков в порядке приоритета.

console.log(i18next.languages);

Пример:

["en-US", "en", "ru"]

Этот массив используется системой fallback-логики:

  • первый элемент — наиболее предпочтительный язык;
  • последующие — резервные варианты;
  • последний обычно соответствует fallbackLng.

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


resolvedLanguage

i18next.resolvedLanguage отражает язык, который фактически был выбран после всех вычислений.

console.log(i18next.resolvedLanguage);

Отличие от language заключается в том, что:

  • language может быть исходным запросом пользователя;
  • resolvedLanguage — язык, реально используемый системой после применения fallback и нормализации.

Пример ситуации:

  • пользователь выбрал en-GB;
  • ресурсов для en-GB нет;
  • система использует en;

В этом случае:

i18next.language = "en-GB"
i18next.resolvedLanguage = "en"

Поведение при инициализации

При запуске экземпляра i18next язык определяется в несколько этапов:

  1. Проверка переданного параметра lng
  2. Запуск language detector (если подключён)
  3. Использование fallbackLng

Пример инициализации:

import i18next from "i18next";

i18next.init({
  lng: "ru",
  fallbackLng: "en",
  resources: {
    ru: {
      translation: {
        hello: "Привет"
      }
    },
    en: {
      translation: {
        hello: "Hello"
      }
    }
  }
});

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


Определение языка через браузер и окружение

В браузерной среде язык часто берётся из:

navigator.language
navigator.languages

Пример значений:

navigator.language = "ru-RU"
navigator.languages = ["ru-RU", "ru", "en-US", "en"]

i18next нормализует эти значения и сопоставляет их с доступными ресурсами.


i18next-browser-languagedetector

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

i18next-browser-languagedetector

Он анализирует несколько источников:

  • localStorage
  • sessionStorage
  • cookie
  • query string
  • navigator
  • HTML tag (<html lang="">)
  • path или subdomain

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

import i18next from "i18next";
import LanguageDetector from "i18next-browser-languagedetector";

i18next
  .use(LanguageDetector)
  .init({
    fallbackLng: "en",
    detection: {
      order: ["querystring", "cookie", "localStorage", "navigator", "htmlTag"],
      caches: ["localStorage", "cookie"]
    }
  });

Приоритет выбора языка

Система определения языка в i18next строится на строгом порядке:

  1. Язык, переданный в changeLanguage
  2. Язык, переданный в init
  3. Язык, найденный через language detector
  4. fallbackLng

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


changeLanguage и обновление текущего языка

Метод changeLanguage изменяет активный язык и обновляет все связанные значения.

i18next.changeLanguage("ru").then(() => {
  console.log(i18next.language);
});

После вызова:

  • обновляется language;
  • пересчитывается resolvedLanguage;
  • перезагружаются ресурсы (если включена динамическая загрузка);
  • вызываются подписчики событий languageChanged.

Пример подписки:

i18next.on("languageChanged", (lng) => {
  console.log("Новый язык:", lng);
});

Различие между language, languages и resolvedLanguage

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

  • language — текущий выбранный язык
  • languages — список fallback-языков
  • resolvedLanguage — фактически применённый язык

Эта структура позволяет:

  • поддерживать fallback-цепочки;
  • учитывать региональные вариации;
  • корректно работать с неполными ресурсами переводов.

Работа в серверной среде (SSR)

В SSR (Server-Side Rendering) определение языка не зависит от браузера. Источники могут быть:

  • HTTP заголовок Accept-Language
  • cookies запроса
  • параметры URL
  • конфигурация сервера

Пример:

i18next.init({
  lng: request.headers["accept-language"],
  fallbackLng: "en"
});

В серверной среде важно фиксировать язык до генерации HTML, поскольку изменение языка после рендера не влияет на уже сформированную разметку.


Нормализация языков

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

  • EN-usen-US
  • ru_ruru-RU
  • PT-brpt-BR

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


Fallback и влияние на текущий язык

Если для выбранного языка отсутствуют переводы, используется цепочка fallback:

fallbackLng: ["en", "de"]

Поведение:

  • система ищет ключ в ru;
  • затем в en;
  • затем в de;
  • если не найдено — возвращается ключ.

Важно, что resolvedLanguage при этом может отличаться от language, поскольку отражает фактически использованный язык из цепочки.


Типичные особенности поведения

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

  • асинхронной загрузки ресурсов;
  • переключения пользователем;
  • синхронизации между вкладками;
  • восстановления состояния из storage;
  • server hydration.

Пример задержки обновления:

await i18next.changeLanguage("de");
console.log(i18next.t("hello"));

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


Синхронизация языка в приложениях

В крупных приложениях язык часто хранится во внешнем состоянии:

  • Redux
  • Zustand
  • Vuex
  • Context API

i18next при этом выступает как источник истины, но состояние может дублироваться для UI-логики.

Пример синхронизации:

i18next.on("languageChanged", (lng) => {
  store.dispatch({ type: "SET_LANGUAGE", payload: lng });
});

Поведение при отсутствии языка

Если язык не может быть определён:

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

В этом случае:

i18next.language // может быть undefined до инициализации

После завершения инициализации значение стабилизируется.


Итоговая модель состояния языка

Состояние языка в i18next можно рассматривать как динамическую систему:

  • вход: пользователь, браузер, сервер, детекторы;
  • обработка: нормализация, fallback, приоритеты;
  • выход: language, resolvedLanguage, languages.

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