Автоопределение языка в i18next реализуется через модуль детекции, который подключается как плагин и управляет тем, откуда и в каком порядке берётся информация о предпочтительном языке интерфейса. Основная задача механизма — определить язык пользователя до выполнения загрузки переводов, чтобы избежать лишних перерисовок интерфейса и «мигания» контента на языке по умолчанию.
В браузерных приложениях стандартным решением является пакет i18next-browser-languagedetector. Он подключается как middleware-плагин и расширяет ядро i18next возможностью анализировать окружение пользователя.
import i18n from 'i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
i18n
.use(LanguageDetector)
.init({
fallbackLng: 'en',
detection: {
order: ['querystring', 'cookie', 'localStorage', 'navigator', 'htmlTag'],
caches: ['localStorage']
}
});
После подключения библиотека автоматически выполняет серию проверок согласно заданному порядку и выбирает первое валидное значение языка.
Ключевой параметр конфигурации — order. Он задаёт
последовательность источников, из которых извлекается язык.
Типичный набор источников:
querystringcookielocalStoragesessionStoragenavigatorhtmlTagpathsubdomainКаждый источник проверяется последовательно. Как только найдено значение, соответствующее поддерживаемому языку, дальнейшие проверки прекращаются.
Язык берётся из параметров URL.
Пример:
https://site.com?lng=ru
Настройка ключа:
detection: {
order: ['querystring'],
lookupQuerystring: 'lng'
}
Этот способ часто используется для тестирования, маркетинговых кампаний и принудительного переключения языка.
Язык извлекается из cookie браузера. Подходит для сохранения выбора пользователя между сессиями.
detection: {
order: ['cookie'],
lookupCookie: 'i18next',
caches: ['cookie']
}
Дополнительные параметры:
cookieDomain — домен, на котором сохраняется
cookiecookieMinutes — срок жизниcookieSecure — использование secure-флагаХранение локального выбора языка без участия сервера.
detection: {
order: ['localStorage'],
lookupLocalStorage: 'i18nextLng'
}
Разница между хранилищами:
localStorage — постоянное хранениеsessionStorage — сброс при закрытии вкладкиЯзык берётся из настроек браузера пользователя через
navigator.language или
navigator.languages.
Пример значений:
ru-RUen-USdei18next автоматически нормализует значения до доступных языков,
например ru-RU → ru.
Язык определяется из атрибута
<html lang="...">.
<html lang="fr">
Используется как резервный источник, особенно в серверно-рендеренных приложениях.
Язык извлекается из URL-пути.
Примеры:
/ru/home
/en/about
Конфигурация:
detection: {
order: ['path'],
lookupFromPathIndex: 0
}
Этот подход характерен для SEO-ориентированных приложений, где язык является частью маршрута.
Язык определяется через поддомен:
ru.site.com
en.site.com
Настройка:
detection: {
order: ['subdomain']
}
После определения языка его можно сохранять в одном или нескольких хранилищах.
detection: {
caches: ['localStorage', 'cookie']
}
Поведение кеширования:
Если ни один источник не дал валидного результата, используется язык по умолчанию:
fallbackLng: 'en'
Также возможно указание нескольких fallback-языков:
fallbackLng: {
'ru-KZ': ['ru', 'en'],
default: ['en']
}
Fallback участвует в цепочке загрузки переводов и влияет на поведение интерполяции ключей.
Детектор может возвращать значения с региональными суффиксами:
en-USen-GBpt-BRi18next использует стратегию нормализации:
en)load: 'languageOnly'i18n.init({
load: 'languageOnly'
});
В Node.js и SSR-режимах основным источником становится HTTP-заголовок:
Accept-Language: ru-RU,ru;q=0.9,en;q=0.8
Используется серверный детектор:
import LanguageDetector from 'i18next-http-middleware';
app.use(LanguageDetector.handle(i18n));
Логика:
qСистема позволяет добавлять собственные источники языка. Каждый детектор реализует интерфейс с методами:
namelookup()cacheUserLanguage()Пример:
const customDetector = {
name: 'customDetector',
lookup() {
return window.myAppLanguage;
},
cacheUserLanguage(lng) {
window.myAppLanguage = lng;
}
};
Подключение:
i18n
.use(LanguageDetector)
.init({
detection: {
order: ['customDetector', 'navigator']
}
});
LanguageDetector.addDetector(customDetector);
Комбинация источников позволяет строить гибкую стратегию определения языка.
Типичный продакшн-порядок:
detection: {
order: [
'querystring',
'cookie',
'localStorage',
'navigator',
'htmlTag',
'path',
'subdomain'
],
caches: ['localStorage', 'cookie']
}
Логика такой последовательности:
При наличии нескольких источников с разными значениями действует правило приоритета:
orderresourcesПример ситуации:
ruendeПри порядке [cookie, navigator, path] итоговым будет
ru.
В одностраничных приложениях детектор выполняется один раз при инициализации. Изменение URL или cookie после загрузки не приводит к автоматическому переключению языка без дополнительного вызова:
i18n.changeLanguage('en');
При необходимости синхронизации с маршрутом требуется ручная интеграция с роутером.
Процесс определения языка выполняется синхронно до загрузки переводов. Время работы зависит от количества источников:
Избыточное количество источников увеличивает только количество операций чтения окружения, но не влияет на сетевые запросы.
Некорректные настройки приводят к нестабильному выбору языка:
fallbackLnglookupQuerystringload: 'languageOnly' с региональными
кодамиorder, где менее приоритетный
источник перекрывает важныйОсобенно критична ситуация, когда navigator стоит выше
cookie, из-за чего пользовательский выбор игнорируется.
Результат детекции напрямую влияет на загрузку файлов переводов:
/locales/{lng}/translation.json
При языке ru загрузится:
/locales/ru/translation.json
Если язык не найден, активируется fallback-цепочка загрузки.
В React, Next.js и Express детектор часто используется совместно с серверным middleware, чтобы обеспечить единый язык на клиенте и сервере.
На сервере:
На клиенте:
Такая схема исключает расхождения между SSR и гидратацией.