В i18next переводы организуются вокруг концепции namespace (пространств имён). Namespace представляет собой логическое разделение словарей локализации: вместо одного большого файла переводов используется набор специализированных модулей, загружаемых по мере необходимости.
Типичная структура:
common — базовые UI-строкиauth — тексты авторизацииprofile — пользовательский профильerrors — сообщения ошибокТакая декомпозиция снижает объём начальной загрузки и позволяет управлять переводами как независимыми единицами.
Асинхронная загрузка namespace становится ключевым механизмом при работе в SPA и SSR-гибридных приложениях, где невозможно или нежелательно загружать весь словарь заранее.
Асинхронность в i18next реализуется через слой backend connector, который отвечает за получение переводов из внешнего источника: HTTP, файловой системы или кастомного API.
Наиболее распространённый вариант — использование HTTP backend:
import i18n from 'i18next';
import HttpBackend from 'i18next-http-backend';
i18n
.use(HttpBackend)
.init({
lng: 'ru',
fallbackLng: 'en',
ns: ['common'],
defaultNS: 'common',
backend: {
loadPath: '/locales/{{lng}}/{{ns}}.json'
}
});
В этой конфигурации namespace не загружаются автоматически полностью. Каждый namespace запрашивается отдельно при первом обращении.
Асинхронная загрузка активируется при обращении к ключам, отсутствующим в текущем кеше. Если namespace не был загружен, i18next инициирует запрос через backend connector.
Пример структуры файлов:
/locales
/ru
common.json
auth.json
/en
common.json
auth.json
Файл auth.json может быть загружен только при первом
использовании:
t('auth:login.title');
Здесь auth — namespace, который может быть подгружен
асинхронно.
Помимо ленивого механизма существует прямой API для управления загрузкой:
i18n.loadNamespaces('auth');
Метод возвращает Promise и инициирует запрос к backend:
i18n.loadNamespaces('auth').then(() => {
const label = i18n.t('auth:login.title');
});
Поддерживается загрузка нескольких namespace одновременно:
i18n.loadNamespaces(['auth', 'profile']);
Для контроля состояния используется проверка наличия загруженного namespace:
i18n.hasLoadedNamespace('auth');
Возвращаемое значение позволяет определить, требуется ли асинхронный запрос перед использованием ключей.
Асинхронная модель включает загрузку не только namespace, но и языков целиком.
i18n.loadLanguages('ru');
Внутренне это может инициировать серию запросов:
При смене языка:
i18n.changeLanguage('en');
может происходить повторная загрузка тех же namespace, если они ещё не закэшированы для нового языка.
После первой загрузки namespace сохраняется в памяти i18next. Повторные обращения не инициируют сетевые запросы.
Ключевые свойства поведения:
lng + nst()reloadResourcesПринудительная перезагрузка:
i18n.reloadResources('ru', 'auth');
Если namespace отсутствует или запрос не удался, применяется fallback-цепочка:
fallbackLng)defaultNS)Пример конфигурации:
i18n.init({
fallbackLng: 'en',
defaultNS: 'common',
ns: ['common', 'auth']
});
При отсутствии ru/auth.json система автоматически
обращается к en/auth.json.
Асинхронная модель i18next строится вокруг очереди запросов:
Внутренне используется сервис:
i18n.services.backendConnector
Он агрегирует запросы, предотвращая дублирование загрузок одного namespace.
При большом количестве namespace система может объединять запросы, если backend это поддерживает.
Пример оптимизации:
auth, profile,
errorsНекоторые backend-реализации поддерживают batch API:
/locales/ru?ns=auth,profile,errors
Асинхронная загрузка namespace часто связывается с динамическими импортами модулей:
import('features/auth').then(() => {
i18n.loadNamespaces('auth');
});
Это позволяет синхронизировать загрузку UI-фичи и соответствующих переводов.
Типичный сценарий:
i18next предоставляет события, отражающие асинхронное состояние:
i18n.on('loaded', (loaded) => {});
i18n.on('failedLoading', (lng, ns) => {});
i18n.on('languageChanged', (lng) => {});
Событие loaded содержит информацию о загруженных
ресурсах и позволяет отслеживать момент завершения асинхронной
операции.
При использовании нескольких namespace одновременно система разрешает ключи по приоритету:
i18n.init({
ns: ['common', 'auth', 'profile'],
defaultNS: 'common'
});
Поиск ключа:
auth:login.title
Алгоритм:
authcommonЕсли одновременно инициируется несколько запросов одного namespace, backendConnector объединяет их:
Это предотвращает состояние race condition при массовом рендере компонентов.
Асинхронная загрузка может быть переведена в синхронный режим при необходимости:
i18n.init({
initImmediate: false
});
В этом случае инициализация блокируется до завершения загрузки ресурсов, включая namespace.
В некоторых архитектурах применяется предзагрузка критических namespace:
i18n.loadNamespaces(['common', 'errors']);
После этого приложение работает без задержек при обращении к базовым ключам, а остальные namespace догружаются по требованию.
Дополнительный подход — загрузка при смене маршрута:
/auth → auth/profile → profileПри недоступности backend система сохраняет работоспособность:
При этом события failedLoading фиксируют проблемные
namespace:
i18n.on('failedLoading', (lng, ns, msg) => {});
Асинхронность namespace не влияет на механизм интерполяции, однако может приводить к временному отсутствию значений:
t('auth:welcome', { name: user.name });
Если namespace ещё не загружен, возвращается fallback или ключ, после чего при завершении загрузки происходит повторное разрешение переводов в UI-слое.
При масштабировании приложения важны следующие аспекты:
Асинхронная модель i18next позволяет распределять нагрузку по времени, снижая пиковые запросы при старте приложения.