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

i18next

Механизм определения языка в i18next основан на модульной системе detection, которая позволяет извлекать язык пользователя из различных источников: URL, cookies, localStorage, HTTP-заголовков, параметров запроса и окружения браузера или сервера. Логика detection выполняется до инициализации словарей переводов и напрямую влияет на выбор активного языка приложения.

Порядок определения языка (order)

Основная настройка — order, задающая последовательность источников:

import i18n from 'i18next';
import LanguageDetector from 'i18next-browser-languagedetector';

i18n
  .use(LanguageDetector)
  .init({
    detection: {
      order: ['querystring', 'cookie', 'localStorage', 'navigator', 'htmlTag', 'path', 'subdomain']
    }
  });

Каждый источник проверяется последовательно. Первый найденный валидный язык становится активным. Отсутствие строгого порядка приводит к неопределённости поведения, особенно в окружениях с пересекающимися источниками (например, cookie и localStorage одновременно).


Источники определения языка

querystring

Извлечение языка из параметров URL:

https://example.com?lng=de

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

detection: {
  lookupQuerystring: 'lng'
}

Используется в сценариях, где язык передаётся явно через ссылку. Подходит для маркетинговых страниц, email-кампаний и SSR-роутинга.


Чтение языка из cookie обеспечивает стабильность между сессиями:

detection: {
  lookupCookie: 'i18next',
  cookieMinutes: 10080
}

Ключевые параметры:

  • lookupCookie — имя cookie
  • cookieMinutes — время жизни
  • cookieDomain — домен хранения
  • cookieOptions — дополнительные настройки (secure, sameSite и др.)

Пример:

detection: {
  lookupCookie: 'lng',
  cookieDomain: '.example.com',
  cookieOptions: {
    sameSite: 'strict',
    secure: true
  }
}

localStorage

Подходит для SPA, где язык хранится на стороне клиента:

detection: {
  lookupLocalStorage: 'i18nextLng'
}

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


sessionStorage

Аналог localStorage, но с ограничением сессии браузера:

detection: {
  lookupSessionStorage: 'i18nextLng'
}

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


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

detection: {
  order: ['navigator']
}

Источник использует:

  • navigator.language
  • navigator.languages

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

  • en-US
  • ru-RU
  • de

htmlTag

Извлечение языка из атрибута lang HTML-документа:

<html lang="ru">

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

detection: {
  lookupFromHtmlTag: true
}

Особенно актуально для серверного рендеринга и статических сайтов.


path

Определение языка из URL-пути:

https://example.com/ru/home

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

detection: {
  order: ['path'],
  lookupFromPathIndex: 0
}

Параметр lookupFromPathIndex определяет сегмент пути:

  • 0/ru/...
  • 1/app/ru/...

subdomain

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

ru.example.com
en.example.com

Настройка:

detection: {
  order: ['subdomain']
}

Полезно для мульти-региональных систем с отдельными доменными зонами.


Кэширование результата detection

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

detection: {
  caches: ['localStorage', 'cookie']
}

Поддерживаемые варианты:

  • localStorage
  • sessionStorage
  • cookie

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


Исключение кеширования

Некоторые языки могут быть исключены из кеширования:

detection: {
  excludeCacheFor: ['cimode']
}

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


Фильтрация и валидация языков

checkWhitelist / supportedLngs

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

i18n.init({
  supportedLngs: ['en', 'ru', 'de'],
  detection: {
    checkWhitelist: true
  }
});

Если обнаруженный язык отсутствует в списке, применяется fallback.


nonExplicitSupportedLngs

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

  • en-USen
  • ru-RUru
i18n.init({
  nonExplicitSupportedLngs: true
});

convertDetectedLanguageFrom

Иногда браузеры возвращают устаревшие или нестандартные коды:

detection: {
  convertDetectedLanguageFrom: 'ISO-639-1'
}

Обеспечивает нормализацию формата языка.


fallbackLng и взаимодействие с detection

При отсутствии результата detection используется резервный язык:

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

Fallback вступает в силу при следующих условиях:

  • язык не найден ни в одном источнике
  • язык не поддерживается
  • detection отключён

load: стратегия загрузки языков

Хотя параметр load не относится напрямую к detection, он влияет на интерпретацию результата:

i18n.init({
  load: 'languageOnly'
});

Варианты:

  • all — полный код (en-US)
  • languageOnly — только язык (en)
  • currentOnly — только текущий

При использовании detection это влияет на нормализацию результата.


HTML integration и автоматическая синхронизация

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

detection: {
  htmlTag: document.documentElement
}

Изменение языка в runtime может отражаться на DOM:

document.documentElement.lang = i18n.language;

Node.js окружение

В серверной среде отсутствуют browser API, поэтому detection строится иначе:

  • HTTP headers (accept-language)
  • кастомные функции lookupHeader
detection: {
  order: ['header'],
  lookupHeader: 'accept-language'
}

Пример Express интеграции:

app.use((req, res, next) => {
  i18n.init({
    lng: req.headers['accept-language']
  });
  next();
});

Приоритет источников и конфликтные сценарии

При одновременном наличии нескольких источников применяется строгая последовательность order. Например:

order: ['cookie', 'querystring', 'localStorage', 'navigator']

Поведение:

  1. cookie имеет приоритет
  2. querystring переопределяет только при отсутствии cookie
  3. localStorage используется как fallback клиента
  4. navigator — последний источник

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


reset настройки detection

В некоторых сценариях требуется сброс сохранённого языка:

detection: {
  caches: [],
  order: ['querystring', 'navigator']
}

или программно:

localStorage.removeItem('i18nextLng');

Типовые конфигурационные шаблоны

SPA (React/Vue)

detection: {
  order: ['localStorage', 'navigator'],
  caches: ['localStorage']
}

SSR (Node + Express)

detection: {
  order: ['header', 'cookie'],
  caches: ['cookie']
}

Multi-domain

detection: {
  order: ['subdomain', 'cookie'],
  lookupCookie: 'lng'
}

URL-driven routing

detection: {
  order: ['path', 'querystring'],
  lookupFromPathIndex: 0,
  lookupQuerystring: 'lng'
}