Получайте уведомления о предстоящих релизах Intlayer
    Создание:2025-08-23Последнее обновление:2025-09-29

    next-i18next ПРОТИВ next-intl ПРОТИВ intlayer | Интернационализация (i18n) Next.js

    Давайте рассмотрим сходства и различия между тремя вариантами i18n для Next.js: next-i18next, next-intl и Intlayer.

    Это не полный учебник. Это сравнение, чтобы помочь вам сделать выбор.

    Мы сосредотачиваемся на Next.js 13+ App RouterReact Server Components) и оцениваем:

    1. Архитектура и организация контента
    2. TypeScript и безопасность
    3. Обработка отсутствующих переводов
    4. Маршрутизация и промежуточное ПО
    5. Производительность и поведение при загрузке
    6. Опыт разработчика (DX), инструменты и сопровождение
    7. SEO и масштабируемость для крупных проектов

    Кратко: Все три решения могут локализовать приложение Next.js. Если вам нужен контент, ограниченный компонентом, строгие типы TypeScript, проверки отсутствующих ключей во время сборки, дерево-шейкнутые словари и первоклассная поддержка App Router + SEO помощников, то Intlayer — самый полный и современный выбор.

    Одна из распространённых ошибок разработчиков — считать, что next-intl — это версия react-intl для Next.js. Это не так — next-intl поддерживается Amann, а react-intl поддерживается FormatJS.


    Кратко

    • next-intl — лёгкое и простое форматирование сообщений с надёжной поддержкой Next.js. Обычно используются централизованные каталоги; опыт разработчика (DX) простой, но безопасность и масштабное сопровождение в основном остаются вашей ответственностью.
    • next-i18next — i18next в обёртке Next.js. Зрелая экосистема и функции через плагины (например, ICU), но конфигурация может быть многословной, а каталоги имеют тенденцию к централизации по мере роста проектов.
    • Intlayer — компонентно-ориентированная модель контента для Next.js, строгая типизация TS, проверки во время сборки, tree-shaking, встроенные middleware и SEO-помощники, опциональный Визуальный редактор/CMS и переводы с помощью ИИ.

    Library GitHub Stars Total Commits Last Commit First Version NPM Version NPM Downloads
    aymericzip/intlayer GitHub Repo stars GitHub commit activity Last Commit April 2024 npm npm downloads
    amannn/next-intl GitHub Repo stars GitHub commit activity Last Commit Nov 2020 npm npm downloads
    i18next/i18next GitHub Repo stars GitHub commit activity Last Commit Jan 2012 npm npm downloads
    i18next/next-i18next GitHub Repo stars GitHub commit activity Last Commit Nov 2018 npm npm downloads

    Значки обновляются автоматически. Снимки будут меняться со временем.


    Сравнение функций бок о бок (с фокусом на Next.js)

    | Функция | next-intlayer (Intlayer) | next-intl | next-i18next |

    Значки обновляются автоматически. Снимки будут меняться со временем.


    Сравнение функций бок о бок (с акцентом на Next.js)

    Функция next-intlayer (Intlayer) next-intl next-i18next
    Переводы рядом с компонентами ✅ Да, контент расположен вместе с каждым компонентом ❌ Нет ❌ Нет
    Интеграция с TypeScript ✅ Продвинутая, автоматически сгенерированные строгие типы ✅ Хорошая ⚠️ Базовая
    Обнаружение отсутствующих переводов ✅ Подсветка ошибок TypeScript и ошибки/предупреждения во время сборки ⚠️ Запасной вариант во время выполнения ⚠️ Запасной вариант во время выполнения
    Богатый контент (JSX/Markdown/компоненты) ✅ Прямая поддержка ❌ Не предназначено для сложных узлов ⚠️ Ограниченно
    Перевод с использованием ИИ ✅ Да, поддерживает нескольких провайдеров ИИ. Можно использовать с собственными API-ключами. Учитывает контекст вашего приложения и объем контента ❌ Нет ❌ Нет
    Визуальный редактор ✅ Да, локальный визуальный редактор + опциональная CMS; может вынести содержимое кодовой базы; встраиваемый ❌ Нет / доступно через внешние платформы локализации ❌ Нет / доступно через внешние платформы локализации
    Локализованный роутинг ✅ Да, поддерживает локализованные пути из коробки (работает с Next.js и Vite) ✅ Встроенный, App Router поддерживает сегмент [locale] ✅ Встроенный
    Генерация динамических маршрутов ✅ Да ✅ Да ✅ Да
    Плюрализация ✅ Шаблоны на основе перечислений ✅ Хорошо ✅ Хорошо
    Форматирование (даты, числа, валюты) ✅ Оптимизированные форматтеры (Intl под капотом) ✅ Хорошо (помощники Intl) ✅ Хорошо (помощники Intl)
    Формат контента ✅ .tsx, .ts, .js, .json, .md, .txt, (.yaml в разработке) ✅ .json, .js, .ts ⚠️ .json
    Поддержка ICU ⚠️ В разработке ✅ Да ⚠️ Через плагин (i18next-icu)
    SEO помощники (hreflang, sitemap) ✅ Встроенные инструменты: помощники для sitemap, robots.txt, метаданных ✅ Хорошо ✅ Хорошо
    Экосистема / Сообщество ⚠️ Меньше, но быстро растет и активно развивается ✅ Хорошо ✅ Хорошо
    Серверный рендеринг и серверные компоненты ✅ Да, оптимизировано для SSR / React Server Components ⚠️ Поддерживается на уровне страниц, но необходимо передавать t-функции в дерево компонентов для дочерних серверных компонентов ⚠️ Поддерживается на уровне страниц, но необходимо передавать t-функции в дерево компонентов для дочерних серверных компонентов
    Tree-shaking (загрузка только используемого контента) ✅ Да, по компонентам во время сборки через плагины Babel/SWC ⚠️ Частично ⚠️ Частично
    Ленивая загрузка ✅ Да, по локалям / по словарям ✅ Да (по маршруту/по локали), требуется управление пространствами имён ✅ Да (по маршруту/по локали), требуется управление пространствами имён
    Очистка неиспользуемого контента ✅ Да, по словарю во время сборки ❌ Нет, можно управлять вручную с помощью управления пространствами имён ❌ Нет, можно управлять вручную с помощью управления пространствами имён
    Управление крупными проектами ✅ Поощряет модульность, подходит для дизайн-систем ✅ Модульное с настройкой ✅ Модульное с настройкой
    Тестирование отсутствующих переводов (CLI/CI) ✅ CLI: npx intlayer content test (аудит, удобный для CI) ⚠️ Не встроено; в документации предлагается npx @lingual/i18n-check ⚠️ Не встроено; полагаться на инструменты i18next / runtime saveMissing

    Введение

    Next.js предоставляет встроенную поддержку интернационализированной маршрутизации (например, сегменты локали). Но эта функция сама по себе не выполняет переводы. Вам все равно нужна библиотека для отображения локализованного контента вашим пользователям.

    Существует множество библиотек для i18n, но в мире Next.js сегодня три из них набирают популярность: next-i18next, next-intl и Intlayer.


    Архитектура и масштабируемость

    • next-intl / next-i18next: По умолчанию используют централизованные каталоги для каждой локали (плюс пространства имён в i18next). Хорошо работает на начальных этапах, но часто становится большой общей областью с растущей связанностью и частой сменой ключей.
    • Intlayer: Поощряет использование словарей на уровне компонентов (или функций), расположенных рядом с кодом, который они обслуживают. Это снижает когнитивную нагрузку, облегчает дублирование/миграцию частей интерфейса и уменьшает конфликты между командами. Неиспользуемый контент естественным образом легче обнаружить и удалить.

    Почему это важно: В больших кодовых базах или при использовании дизайн-систем модульный контент масштабируется лучше, чем монолитные каталоги.


    Размеры бандлов и зависимости

    После сборки приложения, бандл — это JavaScript, который браузер загрузит для отображения страницы. Размер бандла, следовательно, важен для производительности приложения.

    В контексте бандла многоязычного приложения важны два компонента:

    • Код приложения
    • Контент, загружаемый браузером

    Код приложения

    Важность кода приложения в данном случае минимальна. Все три решения поддерживают tree-shaking, что означает, что неиспользуемые части кода не включаются в бандл.

    Вот сравнение размера JavaScript-бандла, загружаемого браузером для многоязычного приложения с использованием трех решений.

    Если в приложении не нужен никакой форматтер, список экспортируемых функций после tree-shaking будет следующим:

    • next-intlayer: useIntlayer, useLocale, NextIntlClientProvider, (Размер бандла 180.6 кБ -> 78.6 кБ (gzip))
    • next-intl: useTranslations, useLocale, NextIntlClientProvider, (Размер бандла 101.3 кБ -> 31.4 кБ (gzip))
    • next-i18next: useTranslation, useI18n, I18nextProvider, (Размер бандла 80.7 кБ -> 25.5 кБ (gzip))

    Эти функции являются лишь обёртками вокруг контекста/состояния React, поэтому общий вклад библиотеки i18n в размер бандла минимален.

    Intlayer немного больше, чем next-intl и next-i18next, потому что включает больше логики в функции useIntlayer. Это связано с интеграцией markdown и intlayer-editor.

    Контент и переводы

    Эта часть часто игнорируется разработчиками, но давайте рассмотрим случай приложения, состоящего из 10 страниц на 10 языках. Предположим, что каждая страница содержит 100% уникального контента для упрощения расчёта (на самом деле, много контента повторяется между страницами, например, заголовок страницы, шапка, подвал и т.д.).

    Пользователь, желающий посетить страницу /fr/about, загрузит контент одной страницы на данном языке. Игнорирование оптимизации контента означало бы ненужную загрузку 8200% ((1 + (((10 страниц - 1) × (10 языков - 1)))) × 100) контента приложения. Видите проблему? Даже если этот контент остаётся текстом, и хотя вы, вероятно, предпочитаете думать об оптимизации изображений на вашем сайте, вы отправляете бесполезный контент по всему миру и заставляете компьютеры пользователей обрабатывать его зря.

    Две важные задачи:

    • Разделение по маршруту:

      Если я нахожусь на странице /about, я не хочу загружать содержимое страницы /home

    • Разделение по локали:

      Если я нахожусь на странице /fr/about, я не хочу загружать содержимое страницы /en/about

    Опять же, все три решения осведомлены об этих проблемах и позволяют управлять этими оптимизациями. Разница между тремя решениями заключается в опыте разработчика (DX).

    next-intl и next-i18next используют централизованный подход к управлению переводами, позволяющий разделять JSON по локалям и по подфайлам. В next-i18next мы называем JSON-файлы «пространствами имён» (namespaces); next-intl позволяет объявлять сообщения. В intlayer мы называем JSON-файлы «словарями» (dictionaries).

    • В случае с next-intl, как и с next-i18next, контент загружается на уровне страницы/макета, затем этот контент загружается в провайдер контекста. Это означает, что разработчик должен вручную управлять JSON-файлами, которые будут загружены для каждой страницы.

    На практике это означает, что разработчики часто пропускают эту оптимизацию, предпочитая для простоты загружать весь контент в провайдер контекста страницы.

    • В случае с intlayer весь контент загружается в приложении. Затем плагин (@intlayer/babel / @intlayer/swc) заботится об оптимизации бандла, загружая только тот контент, который используется на странице. Следовательно, разработчику не нужно вручную управлять словарями, которые будут загружены. Это позволяет добиться лучшей оптимизации, лучшей поддерживаемости и сокращает время разработки.

    По мере роста приложения (особенно когда над приложением работают несколько разработчиков) часто забывают удалять из JSON-файлов контент, который больше не используется.

    Обратите внимание, что во всех случаях загружается весь JSON (next-intl, next-i18next, intlayer).

    Именно поэтому подход Intlayer более производительный: если компонент больше не используется, его словарь не загружается в бандл.

    Также важно, как библиотека обрабатывает fallback. Рассмотрим, что приложение по умолчанию на английском языке, и пользователь заходит на страницу /fr/about. Если переводы на французском отсутствуют, будет использоваться английский fallback.

    В случае с next-intl и next-i18next библиотека требует загрузки JSON, связанного с текущей локалью, а также с локалью-резервом. Таким образом, учитывая, что весь контент переведен, каждая страница загрузит 100% ненужного контента. В сравнении с этим, intlayer обрабатывает резервный вариант на этапе сборки словаря. Таким образом, каждая страница загрузит только используемый контент.

    Вот пример влияния оптимизации размера бандла с использованием intlayer в приложении на vite + react:

    Оптимизированный бандл Неоптимизированный бандл
    оптимизированный бандл неоптимизированный бандл

    TypeScript и безопасность

    next-intl

    • Надёжная поддержка TypeScript, но ключи по умолчанию не строго типизированы; вам придётся вручную поддерживать паттерны безопасности.

    next-i18next

    • Базовые типы для хуков; строгая типизация ключей требует дополнительного инструментария/конфигурации.

    intlayer

    • Генерирует строгие типы на основе вашего контента. Автодополнение в IDE и ошибки на этапе компиляции ловят опечатки и отсутствующие ключи до деплоя.

    Почему это важно: Строгая типизация сдвигает ошибки влево (CI/сборка), а не вправо (во время выполнения).


    Обработка отсутствующих переводов

    next-intl

    • Опирается на запасные варианты во время выполнения (например, показывает ключ или локаль по умолчанию). Сборка не прерывается.

    next-i18next

    • Опирается на запасные варианты во время выполнения (например, показывает ключ или локаль по умолчанию). Сборка не прерывается.

    intlayer

    • Обнаружение на этапе сборки с предупреждениями/ошибками для отсутствующих локалей или ключей.

    Почему это важно: Обнаружение пробелов во время сборки предотвращает появление «непонятных строк» в продакшене и соответствует строгим требованиям к выпуску.


    Маршрутизация, middleware и стратегия URL

    next-intl

    • Работает с локализованной маршрутизацией Next.js на App Router.

    next-i18next

    • Работает с локализованной маршрутизацией Next.js на App Router.

    intlayer

    • Всё вышеперечисленное, плюс i18n middleware (определение локали через заголовки/куки) и хелперы для генерации локализованных URL и тегов <link rel="alternate" hreflang="…">.

    Почему это важно: Меньше пользовательских прослоек; последовательный UX и чистое SEO для всех локалей.


    Совместимость с серверными компонентами (RSC)

    next-intl

    • Поддерживает Next.js 13+. Часто требует передачи t-функций/форматтеров через дерево компонентов в гибридных настройках.

    next-i18next

    • Поддерживает Next.js 13+. Аналогичные ограничения при передаче утилит перевода через границы.

    intlayer

    • Поддерживает Next.js 13+ и сглаживает границу сервер/клиент с помощью единого API и провайдеров, ориентированных на RSC, избегая передачи форматтеров или функций t.

    Почему это важно: Более чистая ментальная модель и меньше крайних случаев в гибридных деревьях.


    DX, инструменты и сопровождение

    next-intl

    • Обычно используется вместе с внешними платформами локализации и редакционными рабочими процессами.

    next-i18next

    • Обычно используется вместе с внешними платформами локализации и редакционными рабочими процессами.

    intlayer

    • Поставляется с бесплатным Визуальным Редактором и опциональной CMS (дружелюбной к Git или внешней), а также с расширением для VSCode и переводами с помощью ИИ, использующими ваши собственные ключи провайдера.

    Почему это важно: Снижает операционные затраты и сокращает цикл взаимодействия между разработчиками и авторами контента.

    Интеграция с платформами локализации (TMS)

    Крупные организации часто используют Системы Управления Переводами (TMS), такие как Crowdin, Phrase, Lokalise, Localizely или Localazy.

    • Почему это важно для компаний

      • Сотрудничество и роли: В процесс вовлечены разные участники: разработчики, менеджеры продуктов, переводчики, рецензенты, маркетинговые команды.
      • Масштаб и эффективность: непрерывная локализация, проверка в контексте.
    • next-intl / next-i18next

      • Обычно используют централизованные JSON-каталоги, поэтому экспорт/импорт с TMS является простым.
      • Зрелые экосистемы и примеры/интеграции для перечисленных платформ.
    • Intlayer

      • Поощряет использование децентрализованных словарей по компонентам и поддерживает контент в форматах TypeScript/TSX/JS/JSON/MD.
      • Это улучшает модульность кода, но может усложнить интеграцию с TMS, когда инструмент ожидает централизованные, плоские JSON-файлы.
      • Intlayer предлагает альтернативы: переводы с помощью ИИ (с использованием ваших собственных ключей провайдера), Визуальный редактор/CMS и рабочие процессы CLI/CI для обнаружения и предварительного заполнения пробелов.

    Примечание: next-intl и i18next также поддерживают каталоги на TypeScript. Если ваша команда хранит сообщения в файлах .ts или децентрализует их по функционалу, вы можете столкнуться с аналогичными трудностями при интеграции с TMS. Однако многие настройки next-intl остаются централизованными в папке locales/, что немного облегчает рефакторинг в JSON для TMS.

    Опыт разработчика

    В этой части проводится глубокое сравнение трех решений. Вместо рассмотрения простых случаев, описанных в документации "начало работы" для каждого решения, мы рассмотрим реальный кейс, более похожий на настоящий проект.

    Структура приложения

    Структура приложения важна для обеспечения хорошей поддерживаемости вашего кода.

    .├── i18n.ts├── locales│   ├── en│   │  ├── home.json│   │  └── navbar.json│   ├── fr│   │  ├── home.json│   │  └── navbar.json│   └── es│      ├── home.json│      └── navbar.json└── src    ├── middleware.ts    ├── app    │   ├── i18n    │   │   └── server.ts    │   └── [locale]    │       └── home.tsx    └── components        └── Navbar            └── index.tsx

    Сравнение

    • next-intl / next-i18next: Централизованные каталоги (JSON; пространства имён/сообщения). Чёткая структура, хорошо интегрируется с платформами перевода, но может привести к большему количеству изменений в разных файлах по мере роста приложений.
    • Intlayer: Словари .content.{ts|js|json} для каждого компонента, расположенные рядом с компонентами. Облегчает повторное использование компонентов и локальное понимание; добавляет файлы и опирается на инструменты сборки.

    Настройка и загрузка контента

    Как упоминалось ранее, вы должны оптимизировать способ импорта каждого JSON-файла в ваш код. Важен способ, которым библиотека обрабатывает загрузку контента.

    i18n.ts
    import { getRequestConfig } from "next-intl/server";import { notFound } from "next/navigation";// Может быть импортировано из общей конфигурацииconst locales = ["en", "fr", "es"];export default getRequestConfig(async ({ locale }) => {  // Проверяем, что входящий параметр `locale` является допустимым  if (!locales.includes(locale as any)) notFound();  return {    messages: (await import(`../messages/${locale}.json`)).default,  };});
    src/app/[locale]/about/layout.tsx
    import { NextIntlClientProvider } from "next-intl";import { getMessages, unstable_setRequestLocale } from "next-intl/server";import pick from "lodash/pick";export default async function LocaleLayout({  children,  params,}: {  children: React.ReactNode;  params: { locale: string };}) {  const { locale } = params;  // Установить активную локаль запроса для этого серверного рендера (RSC)  unstable_setRequestLocale(locale);  // Сообщения загружаются на стороне сервера через src/i18n/request.ts  // (см. документацию next-intl). Здесь мы передаем на клиент  // только подмножество, необходимое для клиентских компонентов (оптимизация нагрузки).  const messages = await getMessages();  const clientMessages = pick(messages, ["common", "about"]);  const rtlLocales = ["ar", "he", "fa", "ur"];  return (    <html lang={locale} dir={rtlLocales.includes(locale) ? "rtl" : "ltr"}>      <body>        <NextIntlClientProvider locale={locale} messages={clientMessages}>          {children}        </NextIntlClientProvider>      </body>    </html>  );}
    src/app/[locale]/about/page.tsx
    import { getTranslations } from "next-intl/server";import { ClientComponent, ServerComponent } from "@components";export default async function LandingPage({  params,}: {  params: { locale: string };}) {  // Загрузка строго на стороне сервера (без гидратации на клиенте)  const t = await getTranslations("about");  return (    <main>      <h1>{t("title")}</h1>      <ClientComponent />      <ServerComponent />    </main>  );}

    Сравнение

    Все три решения поддерживают загрузку контента и провайдеры для каждой локали.

    • С next-intl/next-i18next вы обычно загружаете выбранные сообщения/пространства имён для каждого маршрута и размещаете провайдеры там, где это необходимо.

    • С Intlayer добавляется анализ во время сборки для определения использования, что может сократить ручное подключение и позволить использовать один корневой провайдер.

    Выбирайте между явным контролем и автоматизацией в зависимости от предпочтений вашей команды.

    Использование в клиентском компоненте

    Рассмотрим пример клиентского компонента, который отображает счётчик.

    Переводы (используется та же структура; загружайте их в сообщения next-intl по своему усмотрению)

    locales/en/about.json
    {  "counter": {    "label": "Counter",    "increment": "Increment"  }}
    locales/fr/about.json
    {  "counter": {    "label": "Compteur",    "increment": "Incrémenter"  }}

    Клиентский компонент

    src/components/ClientComponentExample.tsx
    "use client";import React, { useState } from "react";import { useTranslations, useFormatter } from "next-intl";const ClientComponentExample = () => {  // Область видимости непосредственно для вложенного объекта  const t = useTranslations("about.counter");  const format = useFormatter();  const [count, setCount] = useState(0);  return (    <div>      <p>{format.number(count)}</p>      <button        aria-label={t("label")}        onClick={() => setCount((count) => count + 1)}      >        {t("increment")}      </button>    </div>  );};

    Не забудьте добавить сообщение "about" в клиентские сообщения страницы

    Сравнение

    • Форматирование чисел

      • next-i18next: нет useNumber; используется Intl.NumberFormat (или i18next-icu).
      • next-intl: useFormatter().number(value).
      • Intlayer: встроенный useNumber().
    • Ключи

      • Сохраняйте вложенную структуру (about.counter.label) и используйте хук с соответствующей областью (useTranslation("about") + t("counter.label") или useTranslations("about.counter") + t("label")).
    • Расположение файлов

      • next-i18next ожидает JSON в public/locales/{lng}/{ns}.json.
      • next-intl гибок; загружайте сообщения как настроите.
      • Intlayer хранит контент в словарях TS/JS и разрешает по ключу.

    Использование в серверном компоненте

    Мы рассмотрим случай UI-компонента. Этот компонент является серверным компонентом и должен иметь возможность быть вставленным в качестве дочернего компонента клиента. (страница (серверный компонент) -> клиентский компонент -> серверный компонент). Поскольку этот компонент может быть вставлен как дочерний компонент клиента, он не может быть асинхронным.

    src/components/ServerComponent.tsx
    type ServerComponentProps = {  count: number;  t: (key: string) => string;  formatter: Intl.NumberFormat;};const ServerComponent = ({ t, count, formatter }: ServerComponentProps) => {  const formatted = formatter.format(count);  return (    <div>      <p>{formatted}</p>      <button aria-label={t("label")}>{t("increment")}</button>    </div>  );};

    Поскольку серверный компонент не может быть асинхронным, необходимо передавать переводы и функцию форматирования через пропсы.

    • const t = await getTranslations("about.counter");
    • const formatter = await getFormatter().then((formatter) => formatter.number());

    Intlayer предоставляет безопасные для сервера хуки через next-intlayer/server. Для работы useIntlayer и useNumber используют синтаксис, похожий на хуки клиента, но в основе зависят от серверного контекста (IntlayerServerProvider).

    Метаданные / Sitemap / Robots

    Перевод контента — это отлично. Но часто забывают, что главная цель интернационализации — сделать ваш сайт более видимым для всего мира. I18n — это невероятный рычаг для улучшения видимости вашего сайта.

    Вот список лучших практик по многоязычному SEO.

    • устанавливайте метатеги hreflang в теге <head> > Это помогает поисковым системам понять, какие языки доступны на странице
    • перечислите все переводы страниц в sitemap.xml, используя XML-схему http://www.w3.org/1999/xhtml >
    • не забудьте исключить страницы с префиксами из robots.txt (например, /dashboard, а также /fr/dashboard, /es/dashboard) >
    • используйте пользовательский компонент Link для перенаправления на наиболее локализованную страницу (например, на французском <a href="/fr/about">A propos</a>) >

    Разработчики часто забывают правильно ссылаться на свои страницы в разных локалях.

    src/app/[locale]/about/layout.tsx
    import type { Metadata } from "next";import { locales, defaultLocale } from "@/i18n";import { getTranslations } from "next-intl/server";function localizedPath(locale: string, path: string) {  return locale === defaultLocale ? path : "/" + locale + path;}export async function generateMetadata({  params,}: {  params: { locale: string };}): Promise<Metadata> {  const { locale } = params;  const t = await getTranslations({ locale, namespace: "about" });  const url = "/about";  const languages = Object.fromEntries(    locales.map((locale) => [locale, localizedPath(locale, url)])  );  return {    title: t("title"),    description: t("description"),    alternates: {      canonical: localizedPath(locale, url),      languages: { ...languages, "x-default": url },    },  };}// ... Остальная часть кода страницы
    src/app/sitemap.ts
    import type { MetadataRoute } from "next";import { locales, defaultLocale } from "@/i18n";const origin = "https://example.com";const formatterLocalizedPath = (locale: string, path: string) =>  locale === defaultLocale ? origin + path : origin + "/" + locale + path;export default function sitemap(): MetadataRoute.Sitemap {  const aboutLanguages = Object.fromEntries(    locales.map((l) => [l, formatterLocalizedPath(l, "/about")])  );  return [    {      url: formatterLocalizedPath(defaultLocale, "/about"),      lastModified: new Date(),      changeFrequency: "monthly",      priority: 0.7,      alternates: { languages: aboutLanguages },    },  ];}
    src/app/robots.ts
    import type { MetadataRoute } from "next";import { locales, defaultLocale } from "@/i18n";const origin = "https://example.com";const withAllLocales = (path: string) => [  path,  ...locales    .filter((locale) => locale !== defaultLocale)    .map((locale) => "/" + locale + path),];export default function robots(): MetadataRoute.Robots {  const disallow = [    ...withAllLocales("/dashboard"),    ...withAllLocales("/admin"),  ];  return {    rules: { userAgent: "*", allow: ["/"], disallow },    host: origin,    sitemap: origin + "/sitemap.xml",  };}

    Intlayer предоставляет функцию getMultilingualUrls для генерации многоязычных URL для вашей карты сайта.



    И победитель…

    Это не просто. У каждого варианта есть свои компромиссы. Вот как я это вижу:

    next-intl

    • самый простой, легковесный, с меньшим количеством навязанных решений. Если вы хотите минимальное решение, вам комфортно с централизованными каталогами, и ваше приложение маленькое или среднего размера.

    next-i18next

    • зрелый, полнофункциональный, с множеством плагинов сообщества, но с более высокой стоимостью настройки. Если вам нужна экосистема плагинов i18next (например, расширенные правила ICU через плагины) и ваша команда уже знакома с i18next, принимая больше конфигураций ради гибкости.

    Intlayer

    • создан для современного Next.js, с модульным контентом, типобезопасностью, инструментами и меньшим количеством шаблонного кода. Если вы цените контент, ограниченный компонентом, строгий TypeScript, гарантии на этапе сборки, tree-shaking и встроенные маршрутизацию/SEO/редакторские инструменты — особенно для Next.js App Router, дизайн-систем и больших, модульных кодовых баз.

    Если вы предпочитаете минимальную настройку и готовы к некоторой ручной интеграции, next-intl — хороший выбор. Если вам нужны все функции и вы не боитесь сложности, подойдет next-i18next. Но если вы хотите современное, масштабируемое, модульное решение с встроенными инструментами, Intlayer стремится предоставить это из коробки.

    Альтернатива для корпоративных команд: Если вам нужно проверенное решение, которое отлично работает с устоявшимися платформами локализации, такими как Crowdin, Phrase или другими профессиональными системами управления переводами, рассмотрите next-intl или next-i18next за их зрелую экосистему и проверенные интеграции.

    План развития: Intlayer также планирует разработать плагины, которые будут работать поверх решений i18next и next-intl. Это даст вам преимущества Intlayer в автоматизации, синтаксисе и управлении контентом, сохраняя при этом безопасность и стабильность, обеспечиваемые этими устоявшимися решениями в вашем коде приложения.

    GitHub ЗВЁЗДЫ

    Звёзды на GitHub являются сильным индикатором популярности проекта, доверия сообщества и его долгосрочной актуальности. Хотя они не являются прямой мерой технического качества, они отражают, сколько разработчиков считают проект полезным, следят за его развитием и, вероятно, будут его использовать. Для оценки ценности проекта звёзды помогают сравнивать популярность среди альтернатив и дают представление о росте экосистемы.

    График истории звёзд


    Заключение

    Все три библиотеки успешно справляются с основной локализацией. Разница в том, сколько работы вам придется выполнить, чтобы добиться надежной и масштабируемой настройки в современном Next.js:

    • С Intlayer модульный контент, строгий TS, безопасность на этапе сборки, tree-shaken бандлы и первоклассный App Router + инструменты SEO являются стандартом, а не рутиной.
    • Если ваша команда ценит поддерживаемость и скорость в многоязычном приложении, ориентированном на компоненты, Intlayer предлагает сегодня самый полный опыт.

    Обратитесь к документу «Почему Intlayer?» для получения дополнительной информации.