Backend-плагины в i18next отвечают за загрузку и хранение переводов вне клиентского окружения. Они позволяют отделить слой локализации от приложения, обеспечивая гибкость в выборе источника данных: файловая система, HTTP API, базы данных, облачные хранилища или собственные сервисы.
Ключевая идея заключается в том, что i18next не фиксирует способ получения ресурсов. Вместо этого используется контракт (интерфейс backend), который реализуется конкретным плагином.
i18next разделяет ответственность между несколькими уровнями:
Backend слой отвечает за два основных процесса:
Загрузка переводов
Сохранение переводов
Любой backend для i18next должен реализовать методы:
read(language, namespace, callback)Отвечает за получение перевода.
read(language, namespace, callback) {
// загрузка данных
}
Параметры:
language — код языка (en, ru,
de)namespace — пространство имён (common,
auth, errors)callback(err, data) — возврат результатаcreate(languages, namespace, key, fallbackValue)Используется для записи новых ключей перевода.
create(languages, namespace, key, fallbackValue) {
// сохранение перевода
}
init(services, backendOptions, i18nextOptions)Метод инициализации плагина.
init(services, backendOptions, i18nextOptions) {
this.services = services;
this.options = backendOptions;
}
Один из самых распространённых вариантов — загрузка переводов через HTTP.
Пример использования:
import i18next from 'i18next';
import HttpBackend from 'i18next-http-backend';
i18next
.use(HttpBackend)
.init({
lng: 'ru',
backend: {
loadPath: '/locales/{{lng}}/{{ns}}.json'
}
});
{{lng}} — язык{{ns}} — namespaceИспользуется в серверных приложениях на Node.js.
import Backend from 'i18next-fs-backend';
i18next
.use(Backend)
.init({
lng: 'ru',
backend: {
loadPath: './locales/{{lng}}/{{ns}}.json'
}
});
Некоторые реализации используют комбинацию источников.
import MultiBackend from 'i18next-multiload-backend-adapter';
Логика:
Кеширование снижает количество запросов к источнику данных.
class MemoryCache {
constructor() {
this.store = {};
}
get(key) {
return this.store[key];
}
set(key, value) {
this.store[key] = value;
}
}
class Backend {
constructor(services, options) {
this.cache = new MemoryCache();
this.options = options;
}
read(language, namespace, callback) {
const key = `${language}-${namespace}`;
const cached = this.cache.get(key);
if (cached) return callback(null, cached);
// загрузка данных
}
}
Backend возвращает JSON-структуру:
{
"welcome": "Добро пожаловать",
"auth": {
"login": "Войти",
"logout": "Выйти"
}
}
i18next обрабатывает:
Namespace позволяет разделять переводы по логическим модулям:
common — общие строкиauth — авторизацияprofile — профиль пользователяerrors — ошибкиlocales/
ru/
common.json
auth.json
en/
common.json
auth.json
Backend всегда работает асинхронно, даже если источник синхронный.
Поток выполнения:
Backend обязан корректно возвращать ошибки:
read(language, namespace, callback) {
fetch(url)
.then(res => res.json())
.then(data => callback(null, data))
.catch(err => callback(err, false));
}
Поведение i18next:
Backend напрямую влияет на механизм fallback:
ru → en → default
auth → common → default
Некоторые backend поддерживают загрузку нескольких namespace за один запрос:
loadUrl: '/locales/{{lng}}/bundle?ns={{ns}}'
Переводы загружаются по мере необходимости:
i18next.loadNamespaces(['common', 'auth']);
Backend получает список namespaces и выполняет групповой запрос.
Структура минимального backend:
class CustomBackend {
constructor(services, options = {}) {
this.services = services;
this.options = options;
}
init() {}
read(language, namespace, callback) {
const data = getDataSomehow(language, namespace);
callback(null, data);
}
create(languages, namespace, key, fallbackValue) {
saveTranslation(languages, namespace, key, fallbackValue);
}
}
Подключение:
i18next.use(CustomBackend).init({});
Некоторые реализации поддерживают Promise:
read(language, namespace) {
return fetch(`/api/${language}/${namespace}`)
.then(res => res.json());
}
При работе с HTTP backend учитываются:
backend: {
loadPath: '/locales/{{lng}}/{{ns}}.json',
requestOptions: {
headers: {
Authorization: 'Bearer TOKEN'
}
}
}
Переводы часто размещаются на CDN:
Пример:
https://cdn.example.com/locales/ru/common.json
При изменении переводов требуется обновление:
v1, v2)?hash=abc)/locales/v2/{{lng}}/{{ns}}.json
Backend может поддерживать:
Если namespace загружен частично:
В сложных системах backend может:
Типовая структура:
BackendResponse {
language: string,
namespace: string,
data: object,
timestamp: number
}
Backend часто работает вместе с: