Архитектура международализации в i18next строится вокруг строгого отделения текстовых ресурсов от логики приложения, представления интерфейса и бизнес-правил. Такой подход позволяет изолировать изменения переводов от изменения кода, а также минимизировать зависимость компонентов системы друг от друга.
Ключевая идея заключается в том, что перевод не является частью бизнес-логики и не должен внедряться напрямую в вычисления, условия или структуру данных. Вместо этого формируется отдельный слой, отвечающий исключительно за локализацию.
Инициализация i18next представляет собой отдельный конфигурационный контур, который определяет:
Пример конфигурации:
import i18next from "i18next";
i18next.init({
lng: "en",
fallbackLng: "en",
ns: ["common", "auth"],
defaultNS: "common",
interpolation: {
escapeValue: false
},
resources: {
en: {
common: {
welcome: "Welcome"
}
}
}
});
Инициализация не должна содержать UI-логики или бизнес-правил. Она определяет только механизмы работы системы переводов.
Ресурсы переводов отделяются в самостоятельные структуры данных. Обычно используется разбиение по namespace:
Структура файлов:
locales/
en/
common.json
auth.json
ru/
common.json
auth.json
Пример auth.json:
{
"login": "Login",
"logout": "Logout",
"errors": {
"invalidCredentials": "Invalid credentials"
}
}
Такое разделение обеспечивает независимость доменных модулей и снижает связанность между функциональными частями системы.
UI-компоненты не должны содержать строковых литералов, относящихся к пользовательскому языку. Вместо этого они используют ключи переводов.
Пример React-интеграции:
import { useTranslation } from "react-i18next";
function LoginButton() {
const { t } = useTranslation("auth");
return <button>{t("login")}</button>;
}
Здесь UI-компонент не содержит текста, а только ключ доступа к ресурсу. Это создаёт слой абстракции между интерфейсом и языковыми данными.
Бизнес-логика не должна зависеть от конкретного языка или строковых значений.
Неправильный подход:
if (error === "Invalid credentials") {
// логика обработки
}
Правильный подход:
const ERROR_CODES = {
INVALID_CREDENTIALS: "INVALID_CREDENTIALS"
};
if (errorCode === ERROR_CODES.INVALID_CREDENTIALS) {
// логика обработки
}
А уже UI-слой отображает локализованное сообщение:
t("errors.invalidCredentials");
Таким образом, бизнес-логика оперирует стабильными идентификаторами, а слой i18n отвечает только за отображение.
Namespace в i18next выполняет функцию модульного разделения переводов.
Каждый namespace соответствует определённому домену:
Пример использования:
const { t } = useTranslation("checkout");
t("payment.success");
Это снижает риск коллизий ключей и улучшает масштабируемость проекта.
Интерполяция в i18next используется для подстановки данных в строки, но не должна смешиваться с бизнес-логикой форматирования.
Пример:
t("welcomeUser", { name: "Alex" });
Ресурс:
{
"welcomeUser": "Welcome, {{name}}"
}
Недопустимо формировать строки вручную:
"Welcome, " + user.name
Интерполяция централизуется в i18n-слое, что позволяет:
Обработка множественных форм чисел также выносится в систему переводов.
t("items", { count: 5 });
{
"items_one": "{{count}} item",
"items_other": "{{count}} items"
}
Бизнес-логика не принимает решений о грамматике языка. Она лишь передаёт числовые значения.
Для масштабируемых приложений используется динамическая загрузка переводов.
С использованием backend-плагина:
import Backend from "i18next-http-backend";
i18next.use(Backend).init({
backend: {
loadPath: "/locales/{{lng}}/{{ns}}.json"
}
});
Это переносит ответственность за хранение и доставку переводов на внешний слой инфраструктуры.
Форматирование не должно смешиваться с переводами текста. i18next часто используется совместно с Intl API.
Пример:
const date = new Intl.DateTimeFormat("ru-RU").format(new Date());
Локализация текста и форматирование данных разделяются:
В крупных приложениях формируется слоистая архитектура:
Каждый слой взаимодействует только с соседним уровнем, избегая прямых зависимостей.
<button>Submit</button>
if (t("status") === "Success") {}
const message = `Error: ${error.message}`;
{
"canDelete": "true"
}
Переводы не должны содержать логических флагов или управляющих конструкций.
Использование ключей вместо текстов создаёт стабильный контракт между слоями приложения. Ключ:
t("errors.network.timeout");
Такой подход позволяет изменять текст без влияния на поведение системы.
При росте приложения структура i18n становится модульной:
features/
auth/
i18n/
en.json
ru.json
billing/
i18n/
en.json
ru.json
Каждый модуль владеет собственными переводами, что обеспечивает автономность разработки.
i18next выступает центральным механизмом управления языковым слоем, при этом не вмешиваясь в бизнес-логику и не влияя на структуру данных. Разделение ответственности формирует устойчивую архитектуру, в которой каждый слой системы выполняет строго ограниченную функцию без перекрытия зон ответственности.