Email-уведомления в многоязычных приложениях требуют строгой организации строк интерфейса, поскольку письма часто содержат динамические данные, зависят от контекста пользователя и должны сохранять одинаковую семантику во всех локалях. Библиотека i18next позволяет выстроить систему, в которой email-шаблоны становятся частью единого слоя локализации, а не отдельной подсистемой.
Ключевая идея: email — это тот же набор переводов, что и UI, но с отдельным namespace и расширенными правилами форматирования.
В i18next email-шаблоны обычно выделяются в отдельный namespace, например:
{
"welcomeEmail": {
"subject": "Добро пожаловать, {{name}}!",
"title": "Регистрация завершена",
"body": "Спасибо за регистрацию в сервисе {{appName}}.",
"cta": "Перейти в аккаунт"
}
}
Структура namespace позволяет:
Пример подключения:
import i18next from "i18next";
i18next.init({
lng: "ru",
fallbackLng: "en",
resources: {
ru: {
email: {
welcomeEmail: {
subject: "Добро пожаловать, {{name}}!"
}
}
}
}
});
Email-шаблоны почти всегда содержат динамические значения: имя пользователя, ссылки, номера заказов, даты.
i18next поддерживает интерполяцию через {{ }}:
i18next.t("email:welcomeEmail.subject", {
name: "Алексей"
});
Результат:
Добро пожаловать, Алексей!
Пример HTML-письма:
{
"welcomeEmail": {
"html": "<h1>Привет, {{name}}</h1><p>Перейдите по ссылке: {{link}}</p>"
}
}
Email часто содержит HTML-разметку. Это требует разделения:
Пример:
i18next.t("email:welcomeEmail.html", {
name: "Алексей",
link: "https://example.com/dashboard"
});
Важно учитывать:
Email-шаблоны часто имеют сложную структуру: заголовок, тело, кнопки, подписи.
Пример вложенного JSON:
{
"passwordReset": {
"subject": "Сброс пароля",
"content": {
"greeting": "Здравствуйте, {{name}}",
"instruction": "Для сброса пароля нажмите кнопку ниже",
"button": "Сбросить пароль",
"footer": "Если это были не вы — проигнорируйте письмо"
}
}
}
Использование:
i18next.t("email:passwordReset.content.instruction");
В письмах часто встречаются количества: число заказов, уведомлений, сообщений.
i18next поддерживает plural rules:
{
"orders": {
"one": "У вас {{count}} заказ",
"few": "У вас {{count}} заказа",
"many": "У вас {{count}} заказов"
}
}
Использование:
i18next.t("email:orders", { count: 5 });
Система автоматически выбирает нужную форму для языка.
Email-сообщения часто зависят от роли пользователя или статуса операции.
{
"invite": {
"admin": "Вы приглашены как администратор",
"user": "Вы приглашены как пользователь"
}
}
Вызов:
i18next.t("email:invite", { context: "admin" });
Это позволяет избежать дублирования шаблонов.
Обычно email не генерируется напрямую из UI-кода. Используется отдельный слой:
function buildWelcomeEmail(user) {
return {
subject: i18next.t("email:welcomeEmail.subject", {
name: user.name
}),
html: i18next.t("email:welcomeEmail.html", {
name: user.name,
appName: "MyApp"
})
};
}
Такой подход:
Email-шаблоны часто используются вместе с nodemailer или аналогичными системами:
import nodemailer from "nodemailer";
async function sendEmail(user) {
const email = buildWelcomeEmail(user);
await transporter.sendMail({
to: user.email,
subject: email.subject,
html: email.html
});
}
Локализация полностью отделена от транспорта отправки.
При отсутствии перевода в нужной локали система использует fallback:
i18next.init({
lng: "kk",
fallbackLng: "en"
});
Для email это критично, поскольку отсутствие строки не должно приводить к отправке “пустого” письма.
При росте проекта email-локализация требует строгой архитектуры:
email/
welcomeEmail.json
passwordReset.json
orderConfirmation.json
invoice.json
Каждый файл содержит:
Практика поддержки двух форматов:
{
"welcomeEmail": {
"text": "Добро пожаловать, {{name}}",
"html": "<h1>Добро пожаловать, {{name}}</h1>"
}
}
Это важно для:
Email часто содержит даты и суммы. i18next интегрируется с форматированием через плагины:
i18next.t("email:orderConfirmation.date", {
date: new Date()
});
В переводах:
{
"date": "Дата заказа: {{date, datetime}}"
}
Email часто включает ссылки, зависящие от языка:
{
"cta": "https://example.com/{{lng}}/dashboard"
}
Использование:
i18next.t("email:welcomeEmail.cta", {
lng: i18next.language
});
При генерации большого количества писем важно:
i18next.init({
preload: ["ru", "en", "kk"],
ns: ["email"]
});
При масштабировании применяется единый контракт email-шаблона:
type EmailTemplate = {
subject: string;
text: string;
html: string;
};
И функция-адаптер:
function tEmail(key, params) {
return {
subject: i18next.t(`${key}.subject`, params),
text: i18next.t(`${key}.text`, params),
html: i18next.t(`${key}.html`, params)
};
}
Email становится частью общей системы интернационализации: