В i18next состояние загруженных языков отражается через несколько
внутренних и публичных механизмов, главным из которых является массив
i18n.languages. Он формируется после инициализации и
обновляется при смене языка или загрузке новых ресурсов.
import i18n from 'i18next';
console.log(i18n.languages);
В типичной конфигурации массив может содержать:
en-US,
en)Важно учитывать, что порядок элементов имеет значение: поиск перевода выполняется последовательно по массиву, пока не будет найдено совпадение.
Состояние активного языка хранится отдельно от списка загруженных языков:
console.log(i18n.language);
console.log(i18n.resolvedLanguage);
Различие между ними принципиально:
language — язык, который был установлен вручную или
через changeLanguageresolvedLanguage — итоговый язык после применения
детекции и fallback-цепочкиПример ситуации:
i18n.init({
lng: 'ru-RU',
fallbackLng: 'en'
});
После инициализации возможна нормализация:
language: ru-RUresolvedLanguage: ruОсновная структура, содержащая загруженные переводы:
i18n.services.resourceStore.data
Она организована по схеме:
resourceStore.data = {
lng: {
namespace: {
key: value
}
}
}
Пример доступа:
const store = i18n.services.resourceStore.data;
console.log(store.ru.translation);
console.log(store.en.common);
Каждый уровень структуры играет роль:
ru, en)translation, common,
errors)Перед использованием языка часто требуется проверить, загружен ли он полностью:
const hasRussian = i18n.hasResourceBundle('ru', 'translation');
console.log(hasRussian);
Метод проверяет наличие namespace для конкретного языка в
resourceStore.
Дополнительная проверка:
const exists = i18n.exists('some.key');
Однако exists проверяет ключи переводов, а не сам факт
загрузки языка.
Namespace — базовая единица загрузки в системе интернационализации i18next.
Проверка загруженных namespace:
console.log(i18n.options.ns);
Активные namespace можно получить через:
console.log(i18n.options.defaultNS);
Для проверки конкретного namespace используется:
i18n.hasLoadedNamespace('translation');
Это особенно важно при ленивой загрузке:
await i18n.loadNamespaces('common');
Механизм событий позволяет наблюдать за процессом загрузки:
i18n.on('loaded', (loaded) => {
console.log('Загруженные ресурсы:', loaded);
});
Также полезны события:
initializedlanguageChangedloadedfailedLoadingПример контроля загрузки:
i18n.on('failedLoading', (lng, ns, msg) => {
console.error(lng, ns, msg);
});
Если используется backend-плагин, загрузка языков зависит от асинхронных запросов:
i18n.init({
backend: {
loadPath: '/locales/{{lng}}/{{ns}}.json'
}
});
Проверка завершения загрузки:
i18n.loadNamespaces('translation').then(() => {
console.log('Namespace загружен');
});
getDataByLanguageБолее прямой доступ к данным:
const ruData = i18n.getDataByLanguage('ru');
console.log(ruData);
Результат включает все namespace для указанного языка.
Структура полезна для:
Включение debug-режима раскрывает процесс загрузки языков:
i18n.init({
debug: true
});
В консоли отображаются:
Список поддерживаемых языков обычно задаётся явно:
i18n.init({
supportedLngs: ['en', 'ru', 'de']
});
Доступ к ним:
console.log(i18n.options.supportedLngs);
Это не тождественно загруженным языкам — различие важно:
Языки могут подгружаться динамически:
await i18n.loadLanguages(['ru', 'en']);
Или переключаться:
await i18n.changeLanguage('ru');
После смены языка обновляются:
i18n.languagei18n.languagesДля диагностики используется обход resourceStore:
function inspectStore(i18n) {
const data = i18n.services.resourceStore.data;
Object.keys(data).forEach(lng => {
Object.keys(data[lng]).forEach(ns => {
console.log(lng, ns, Object.keys(data[lng][ns]).length);
});
});
}
inspectStore(i18n);
Такая проверка выявляет:
При асинхронной загрузке возможны состояния гонки. Для их отслеживания используется комбинация событий и проверок:
let isReady = false;
i18n.on('initialized', () => {
isReady = true;
});
i18n.on('loaded', () => {
console.log('Ресурсы обновлены');
});
Fallback-языки участвуют в инспекции загруженных данных:
i18n.init({
fallbackLng: ['en', 'de']
});
Текущая цепочка:
console.log(i18n.languages);
Пример результата:
['ru', 'en', 'de']
Поиск перевода выполняется строго по этому порядку, что напрямую
влияет на результат t().