Механизм nesting в i18next позволяет использовать одну переводную строку внутри другой. Это решает задачу повторного использования текстовых фрагментов и построения составных сообщений без дублирования ключей.
В отличие от интерполяции, где в строку подставляются значения переменных, nesting подставляет результат другой переводной строки, то есть выполняет повторный вызов системы перевода.
Классический синтаксис nesting:
{
"welcome": "Добро пожаловать, $t(user.name)"
}
Здесь user.name — это отдельный ключ перевода, результат
которого вставляется в строку welcome.
Интерполяция в i18next используется для подстановки динамических значений:
{
"greeting": "Привет, {{name}}"
}
В коде:
i18next.t('greeting', { name: 'Алексей' })
Nesting же обращается к другим ключам переводов:
{
"name": "Алексей",
"greeting": "Привет, $t(name)"
}
Различие принципиальное:
Основной инструмент nesting — функция $t() внутри строки
перевода.
Общий формат:
$t(key, options)
Простейший пример:
{
"site": {
"name": "CodeBase"
},
"title": "Добро пожаловать в $t(site.name)"
}
Результат:
Добро пожаловать в CodeBase
Одной из ключевых особенностей i18next является возможность комбинировать nesting и интерполяцию в одной строке.
Пример:
{
"user": {
"name": "Алексей"
},
"message": "Пользователь $t(user.name) имеет {{count}} уведомлений"
}
Вызов:
i18next.t('message', { count: 5 })
Результат:
Пользователь Алексей имеет 5 уведомлений
Здесь происходит два уровня обработки:
$t(user.name) — nesting, извлечение перевода{{count}} — интерполяция runtime-значенияi18next обрабатывает строку перевода поэтапно:
$t(...)){{...}})Это означает, что nesting всегда вычисляется раньше интерполяции.
Пример:
{
"currency": "USD",
"price": "Цена: $t(currency) {{value}}"
}
i18next.t('price', { value: 100 })
Результат:
Цена: USD 100
Nesting поддерживает многоуровневые конструкции, включая рекурсивные вызовы.
{
"company": {
"name": "TechCorp"
},
"product": {
"name": "i18n Suite"
},
"description": "$t(company.name) разработала $t(product.name)"
}
Результат:
TechCorp разработала i18n Suite
Можно строить более глубокие цепочки:
{
"a": "Level A",
"b": "$t(a) → Level B",
"c": "$t(b) → Level C"
}
Результат:
Level A → Level B → Level C
При неправильной структуре переводов возможно возникновение циклов:
{
"a": "$t(b)",
"b": "$t(a)"
}
Такая конструкция приводит к бесконечной рекурсии или остановке по внутреннему лимиту глубины.
Типичные проблемы:
Рекомендуемая практика — избегать взаимных ссылок между ключами, особенно в shared namespaces.
Функция $t() может принимать параметры, аналогично
обычному i18next.t().
{
"items": "У вас {{count}} элементов",
"summary": "$t(items, { count: 10 })"
}
Результат:
У вас 10 элементов
Это позволяет использовать одну базовую строку как шаблон для множества производных сообщений.
Особый случай — когда вложенный ключ сам содержит интерполяцию.
{
"user": {
"name": "Алексей",
"full": "{{name}} Иванов"
},
"greeting": "Привет, $t(user.full)"
}
Результат:
Привет, Алексей Иванов
Порядок обработки:
$t(user.full) → {{name}} Иванов{{name}} не срабатывает, потому что
параметры не переданы на уровень nestingЧтобы это работало корректно, параметры нужно передавать через
$t():
{
"greeting": "Привет, $t(user.full, { name: 'Алексей' })"
}
По умолчанию i18next использует $t() как маркер nesting.
Однако поведение можно кастомизировать через настройки интерполяции:
i18next.init({
interpolation: {
prefix: '{{',
suffix: '}}'
}
})
Важно понимать, что это влияет только на интерполяцию, но не изменяет синтаксис nesting. Nesting регулируется отдельной настройкой:
i18next.init({
nestingPrefix: '$t(',
nestingSuffix: ')'
})
Можно изменить стиль записи:
{
"title": "Hello %{name}"
}
или альтернативные схемы в зависимости от конфигурации проекта.
Nesting часто используется вместе с pluralization и context.
{
"apple": "яблоко",
"apple_plural": "яблоки",
"basket": "Корзина содержит $t(apple, { count: {{count}} })"
}
i18next.t('basket', { count: 3 })
Результат:
Корзина содержит яблоки
Здесь nesting передаёт управление pluralization через вложенный ключ.
Nesting увеличивает количество внутренних вызовов t(),
поэтому при глубокой вложенности возможны накладные расходы.
Ключевые моменты оптимизации:
При большом объёме переводов рекомендуется структурировать словари так, чтобы nesting использовался как вспомогательный инструмент, а не как основа архитектуры.
В проектах с namespace структурами nesting может ссылаться на ключи из других пространств:
{
"common": {
"appName": "Portal"
},
"home": {
"title": "Добро пожаловать в $t(common:appName)"
}
}
Такой подход позволяет централизовать повторно используемые строки и снижает дублирование между модулями приложения.
Если ключ не найден, i18next возвращает fallback:
{
"title": "Добро пожаловать в $t(missing.key)"
}
Результат может быть:
Добро пожаловать в missing.key
или fallback value, если он настроен через конфигурацию
fallbackLng или defaultValue.
В реальных проектах nesting используется для построения модульных сообщений:
{
"brand": {
"name": "NovaApp"
},
"auth": {
"login": "Вход",
"welcome": "Добро пожаловать в $t(brand.name). $t(auth.login)"
}
}
Такой подход позволяет:
Nesting может содержать HTML или форматированные строки:
{
"bold": "<strong>важный текст</strong>",
"message": "Это $t(bold)"
}
Однако при использовании в UI-фреймворках важно учитывать экранирование и безопасность вывода, чтобы избежать XSS при неправильной обработке HTML-строк.
При комбинировании нескольких уровней:
{
"level1": "$t(level2, { value: {{value}} })",
"level2": "Значение: {{value}}"
}
i18next.t('level1', { value: 42 })
Результат:
Значение: 42
Параметры передаются только на уровень, где выполняется
$t(), поэтому важно контролировать контекст передачи
данных.