Автор:
    Создание:2026-09-02Последнее обновление:2026-09-02

    Устарел ли next-intl в 2026 году?

    Когда Vercel представил App Router и убрал встроенную i18n из Pages Router, next-intl оперативно занял освободившуюся нишу. Качественная документация Яна Аманна и своевременная поддержка App Router сделали эту библиотеку выбором по умолчанию для многих разработчиков.

    Почему же сегодня возникает вопрос о ее актуальности?

    Архитектура веба за последние три года сделала большой шаг вперед, тогда как концептуальная модель next-intl осталась на месте.

    Пока Next.js развивал React Server Components (RSC), потоковый рендеринг и оптимизации на уровне компилятора, next-intl продолжает решать интернационализацию во время выполнения: передает тяжелые JSON-объекты клиентским провайдерам, выполняет ICU-форматтеры в браузере и полагается на ручную разбивку по неймспейсам для контроля веса бандла.

    Главные выводы

    Снижение темпов развития:

    За последние 12 месяцев в next-intl добавлено ~187 коммитов, преимущественно связанных с адаптацией к релизам Next.js и мелкими исправлениями.

    Клиентский оверхед в runtime:

    Подключение NextIntlClientProvider с useTranslations() добавляет ~12.8 КБ gzipped (51 КБ minified) еще до вывода текста, что примерно втрое превышает вес next-intlayer (4.3 КБ).

    Утечка 90% переводов:

    В типичных конфигурациях 89.8% объема переводов, передаваемых на страницу, принадлежит другим маршрутам. При переходе на /contact попутно загружаются тексты /pricing и личного кабинета.

    Ручное управление неймспейсами:

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

    Коммерческое партнерство:

    Будучи официальным партнером Crowdin, проект имеет мало причин разрабатывать бесплатную локальную утилиту ИИ-перевода прямо в CLI.

    Поддержка vs. современные инструменты

    Активность коммитов за последние 12 месяцев:

    Репозиторий Звезды Всего коммитов Коммитов / год Последний коммит
    amannn/next-intl stars commits yearly last
    aymericzip/intlayer stars commits yearly last

    Показатели за прошедший год:

    • amannn/next-intl: 187 коммитов (обновления зависимостей и небольшие патчи).
    • aymericzip/intlayer: 4 343 коммита (активная работа над компилятором, плагинами для IDE, MCP-серверами и алгоритмами перевода).

    Star History Chart

    Стабильная библиотека полезна, но подходы к i18n изменились: компиляторы удаляют неиспользуемые строки при сборке, нейросети переводят тексты в CI, а среды разработки подключают LSP и ИИ-помощников. Архитектура, сосредоточенная на времени выполнения, с трудом использует эти возможности.

    Тестирование в Next.js 16 App Router

    Бенчмарк проведен на стандартном приложении App Router с 10 маршрутами и 10 языками:

    Динамическая загрузка JSON

    Ленивая загрузка переводов во время выполнения

    Ограниченный JSON (пространства имен)

    Пространства имен перевода для каждой страницы

    Бенчмарк производительности I18n

    Что это за метрика?

    Общий размер пакета библиотеки интернационализации в формате gzip. Он включает в себя только провайдер и логику извлечения контента после tree-shaking и минификации.

    Почему это важно?

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

    Вид

    Измерения в реальных браузерах с gzip-сжатием. Все подробности в отчете о бенчмарке Next.js.

    Базовый размер библиотек

    Вес клиентской части до добавления текстов:

    Библиотека Gzipped Minified
    next-intl@4.9.1 12.8 КБ 51.0 КБ
    next-intlayer@8.7.12 4.3 КБ 13.3 КБ

    Вес страниц и утечки контента

    Конфигурация Ср. JS / стр. (gz) Утечка языков Утечка др. страниц Ср. компонент (gz)
    База (без i18n) 150.8 КБ 0.0% 0.0% 0.7 КБ
    next-intl (статика) 163.5 КБ 4.2% 89.8% 20.5 КБ
    next-intl (динамика) 163.4 КБ 9.7% 89.9% 20.5 КБ
    next-intlayer 152.1 КБ 0.0% 0.0% 7.2 КБ

    Причина утечек между страницами

    В классических проектах с next-intl корневой layout загружает весь объем переводов сразу:

    app/[locale]/layout.tsx
    export default async function RootLayout({ children, params }) {
      const messages = await getMessages();
    
      return (
        <html>
          <body>
            <NextIntlClientProvider messages={messages}>
              {children}
            </NextIntlClientProvider>
          </body>
        </html>
      );
    }
    

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

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

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

    Почему next-intl не поддается tree-shaking

    Интерфейс библиотеки опирается на строковые вызовы ключей во время выполнения:

    UserProfile.tsx
    "use client";
    
    import { useTranslations } from "next-intl";
    
    export function UserProfile() {
      const t = useTranslations("UserProfile");
    
      return <h2>{t("heading")}</h2>;
    }
    
    UserProfile.tsx
    "use client";
    
    import { useIntlayer } from "next-intlayer";
    
    export function UserProfile() {
      const { heading } = useIntlayer("user-profile");
    
      return <h2>{heading}</h2>;
    }
    

    Turbopack и Webpack не могут предсказать, какие именно ключи из UserProfile будут вызваны. Чтобы не допустить падения приложения, бандлер включает весь неймспейс целиком в клиентский чанк. Деструктурированные свойства в Intlayer позволяют компилятору четко видеть зависимости и вырезать ненужные поля. Подробнее в оптимизации бандла.

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

    Внешний JSON против совместного размещения

    В next-intl тексты хранятся в отдельных JSON-файлах в папке messages/. Intlayer располагает файлы контента рядом с компонентами:

    messages/en.json
    {
      "authModal": {
        "title": "Sign in to your account",
        "submitButton": "Continue"
      }
    }
    
    messages/ru.json
    {
      "authModal": {
        "title": "Войдите в аккаунт",
        "submitButton": "Продолжить"
      }
    }
    
    AuthModal.tsx
    import { useTranslations } from "next-intl";
    
    export const AuthModal = () => {
      const t = useTranslations("authModal");
      return (
        <form>
          <h2>{t("title")}</h2>
          <button type="submit">{t("submitButton")}</button>
        </form>
      );
    };
    
    AuthModal.content.ts
    import { t, type Dictionary } from "intlayer";
    
    export default {
      key: "auth-modal",
      content: {
        title: t({
          en: "Sign in to your account",
          ru: "Войдите в аккаунт",
        }),
        submitButton: t({
          en: "Continue",
          ru: "Продолжить",
        }),
      },
    } satisfies Dictionary;
    
    AuthModal.tsx
    import { useIntlayer } from "next-intlayer";
    
    export const AuthModal = () => {
      const { title, submitButton } = useIntlayer("auth-modal");
      return (
        <form>
          <h2>{title}</h2>
          <button type="submit">{submitButton}</button>
        </form>
      );
    };
    

    При удалении или рефакторинге AuthModal.tsx его переводы перемещаются или удаляются вместе с ним.

    Автодополнение против строгой проверки полноты

    Расширение IntlMessages в next-intl обеспечивает автодополнение в редакторе по основному языковому файлу:

    global.d.ts
    import en from "./messages/en.json";
    
    type Messages = typeof en;
    
    declare global {
      interface IntlMessages extends Messages {}
    }
    

    Однако контроль распространяется лишь на базовый язык. Если ключ пропадет из ru.json, TypeScript не выдаст ошибок, CI останется успешным, а пользователи увидят пустые места.

    Intlayer генерирует типы на основе всех файлов контента. Активация режима strictMode останавливает сборку при отсутствии перевода в любой из указанных локалей.

    Сравнение инструментария и поддержка ИИ

    Возможность next-intl Intlayer
    Расширение VS Code ❌ Нет Официальное расширение
    Language Server (LSP) ❌ Нет Встроенный LSP
    MCP Server (для ИИ-агентов) ❌ Нет Готовый MCP-сервер
    Навыки агентов (Skills) ❌ Нет Доступные навыки
    Визуальная CMS ❌ Нет Бесплатно и Open Source

    Собственные серверы LSP и MCP дают ИИ-ассистентам возможность анализировать структуру контента и точно предлагать или актуализировать переводы.

    Связь с Crowdin и развитие продукта

    next-intl является официальным партнером Crowdin. Спонсорство помогает развивать проект, однако задает приоритеты: ориентируясь на сторонние TMS-платформы, библиотека не ставит целью создание встроенной бесплатной локальной ИИ-утилиты для перевода.

    Intlayer предлагает эти решения из коробки:

    Локальный ИИ-перевод (intlayer fill):

    Находит и переводит недостающие строки через ваши личные API-ключи OpenAI, Anthropic, Mistral или Gemini.

    Автономная визуальная CMS:

    Используйте Intlayer CMS для визуального редактирования с сохранением изменений напрямую в Git.

    Лицензия Apache 2.0:

    Все компоненты экосистемы полностью открыты.

    Где next-intl все еще удобен?

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

    Для команд, чья инфраструктура переводов уже плотно интегрирована с Crowdin, библиотека подходит органично.

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

    Как улучшить текущую конфигурацию next-intl?

    Intlayer предоставляет готовый пакет совместимости, который точно повторяет сигнатуры функций и хуков next-intl (такие как useTranslations, getTranslations и утилиты маршрутизации). Вам не нужно переписывать компоненты или страницы, чтобы получить оптимизацию на уровне компилятора.

    Настройка выполняется одной командой:

    bash
    npx intlayer init --interactive
    

    Интерактивный интерфейс командной строки:

    1. Устанавливает пакет совместимости @intlayer/next-intl.
    2. Настраивает алиасы сборщика, чтобы привычные импорты (next-intl, next-intl/server) прозрачно вели на Intlayer, позволяя удалить старую библиотеку из package.json.
    3. Сразу активирует поддержку языкового сервера (LSP), исключает перекрестные утечки переводов между страницами (полный tree-shaking) и включает локальные процессы ИИ-перевода без масштабного рефакторинга.

    Подробные инструкции можно найти в наших руководствах:

    • Прямая совместимость: Сохраняйте вызовы useTranslations, используя адаптер совместимости с next-intl.
    • Руководство по миграции: Преобразуйте существующие JSON-файлы в типизированные словари с помощью инструкции по миграции.
    • Гибридный вариант: Оставьте next-intl для вывода интерфейса, подключив Intlayer к next-intl для локального перевода через ИИ.

    Оцените вес и утечки вашего проекта с помощью бесплатного SEO-сканера i18n:

    Дополнительные материалы

    Комментарии

    Пока нет комментариев. Будьте первым, кто поделится своими мыслями.

    Похожие сообщения

    Последние сообщения