Creation:2026-01-10Last update:2026-05-31

    Переведите ваш сайт Next.js 16 (без [locale] в пути страницы) с помощью Intlayer | Интернационализация (i18n)

    www.youtube.com

    Смотрите шаблон приложения на GitHub.

    Содержание

    Почему Intlayer лучше альтернатив?

    По сравнению с основными решениями, такими как next-intl или i18next, Intlayer представляет собой решение со встроенными оптимизациями, такими как:

    Intlayer оптимизирован для работы с Серверными компонентами для эффективного рендеринга и полностью совместим с Turbopack. Он не блокирует статический рендеринг и предлагает промежуточное программное обеспечение, а также все функции, необходимые для масштабирования интернационализации (i18n).

    Intlayer совместим с Next.js 12, 13, 14, 15 и 16. Если вы используете маршрутизатор страниц Next.js, вы можете обратиться к этому [руководству] (/ru/doc/environment/nextjs/next-with-page-router). Маршрутизация локали полезна для SEO, размера пакета и производительности. Если вам это не нужно, вы можете обратиться к этому [руководству] (/ru/doc/environment/nextjs/no-locale-path). Для Next.js 12, 13, 14 и 15 с App Router обратитесь к этому [руководству] (/ru/doc/environment/nextjs/14).

    Вместо загрузки огромных файлов JSON на свои страницы загружайте только необходимый контент. Intlayer помогает уменьшить размер бандла и страниц до 50 %.

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

    Совместное размещение контента уменьшает контекст, необходимый для моделей большого языка (LLM). Intlayer также поставляется с набором инструментов, таких как CLI для проверки отсутствия переводов,LSP, MCP, и навыки агента, чтобы сделать работу разработчика (DX) еще более удобной для агентов ИИ.

    Используйте автоматизацию для перевода в своем конвейере CI/CD, используя LLM по вашему выбору за счет вашего поставщика ИИ. Intlayer также предлагает компилятор для автоматизации извлечения контента, а также веб-платформу, которая помогает переводить в фоновом режиме.

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

    Intlayer — это больше, чем просто решение i18n. Он предоставляет автономный визуальный редактор и полный CMS, чтобы помочь вам управлять многоязычным контентом в реальном времени, упрощая сотрудничество с переводчиками, копирайтерами и другими членами команды. Контент может храниться локально и/или удаленно.


    Пошаговое руководство по настройке Intlayer в приложении Next.js

    1. Установка зависимостей

      Установите необходимые пакеты с помощью npm:

      bash
      npm install intlayer next-intlayernpx intlayer init
      • intlayer

        Основной пакет, предоставляющий инструменты интернационализации для управления конфигурацией, переводов, декларации контента, транспиляции и команд CLI.

      • next-intlayer

      Пакет, который интегрирует Intlayer с Next.js. Он предоставляет context providers и хуки для интернационализации в Next.js. Дополнительно он включает плагин Next.js для интеграции Intlayer с Webpack или Turbopack, а также прокси для определения предпочтительной локали пользователя, управления cookies и обработки перенаправлений URL.

    2. Настройка вашего проекта

      Ниже приведена итоговая структура, которую мы получим:

      bash
      .├── src│   ├── app│   │   ├── layout.tsx│   │   ├── page.content.ts│   │   └── page.tsx│   ├── components│   │   ├── clientComponentExample│   │   │   ├── client-component-example.content.ts│   │   │   └── ClientComponentExample.tsx│   │   ├── localeSwitcher│   │   │   ├── localeSwitcher.content.ts│   │   │   └── LocaleSwitcher.tsx│   │   └── serverComponentExample│   │       ├── server-component-example.content.ts│   │       └── ServerComponentExample.tsx│   └── proxy.ts├── intlayer.config.ts├── next.config.ts├── package.json└── tsconfig.json
      Если вы не хотите маршрутизацию по локалям, intlayer можно использовать как простой provider / hook. См. это руководство для получения дополнительных сведений.

      Создайте файл конфигурации для настройки языков вашего приложения:

      intlayer.config.ts
      import { Locales, type IntlayerConfig } from "intlayer";
      
      const config: IntlayerConfig = {
        internationalization: {
          locales: [
            Locales.ENGLISH,
            Locales.FRENCH,
            Locales.SPANISH,
            // Ваши другие локали
          ],
          defaultLocale: Locales.ENGLISH,
        },
        routing: {
          mode: "search-params", // или `no-prefix`, полезно для обнаружения в middleware
        },
      };
      
      export default config;
      С помощью этого файла конфигурации вы можете настроить локализованные URL, перенаправление через прокси, имена cookie, расположение и расширение ваших деклараций контента, отключить логи Intlayer в консоли и многое другое. Для полного списка доступных параметров см. документацию по конфигурации.
    3. Интеграция Intlayer в конфигурацию Next.js

      Настройте ваш проект Next.js для использования Intlayer:

      next.config.ts
      import type { NextConfig } from "next";
      import { withIntlayer } from "next-intlayer/server";
      
      const nextConfig: NextConfig = {
        /* параметры конфигурации здесь */
      };
      
      export default withIntlayer(nextConfig);

      Плагин Next.js withIntlayer() используется для интеграции Intlayer с Next.js. Он обеспечивает генерацию файлов декларации контента и их отслеживание в режиме разработки. Он определяет переменные окружения Intlayer внутри сред Webpack или Turbopack. Дополнительно он предоставляет алиасы для оптимизации производительности и обеспечивает совместимость с серверными компонентами.

      Функция withIntlayer() возвращает Promise. Она позволяет подготовить словари intlayer перед началом сборки. Если вы хотите использовать её вместе с другими плагинами, вы можете дождаться её выполнения с помощью await. Пример:

      ts
      const nextConfig = await withIntlayer(nextConfig);const nextConfigWithOtherPlugins = withOtherPlugins(nextConfig);export default nextConfigWithOtherPlugins;

      Если вы хотите использовать его синхронно, вы можете воспользоваться функцией withIntlayerSync(). Пример:

      ts
      const nextConfig = withIntlayerSync(nextConfig);const nextConfigWithOtherPlugins = withOtherPlugins(nextConfig);export default nextConfigWithOtherPlugins;

      Intlayer автоматически определяет, использует ли ваш проект webpack или Turbopack на основе флагов командной строки --webpack, --turbo или --turbopack, а также вашей текущей версии Next.js.

      Поскольку next>=16, если вы используете Rspack, вы должны явно заставить Intlayer использовать конфигурацию webpack, отключив Turbopack:

      ts
      withRspack(withIntlayer(nextConfig, { enableTurbopack: false }));
    4. Определение динамических маршрутов локализации

      Удалите всё из RootLayout и замените его следующим кодом:

      src/app/layout.tsx
      import type { Metadata } from "next";
      import type { ReactNode } from "react";
      import "./globals.css";
      import { IntlayerClientProvider, LocalPromiseParams } from "next-intlayer";
      import { getHTMLTextDir, getIntlayer } from "intlayer";
      import { getLocale } from "next-intlayer/server";
      export { generateStaticParams } from "next-intlayer";
      
      export const generateMetadata = async (): Promise<Metadata> => {
        const locale = await getLocale();
        const { title, description, keywords } = getIntlayer("metadata", locale);
      
        return {
          title,
          description,
          keywords,
        };
      };
      
      const RootLayout = async ({
        children,
      }: Readonly<{
        children: ReactNode;
      }>) => {
        const locale = await getLocale();
      
        return (
          <html lang={locale} dir={getHTMLTextDir(locale)}>
            <IntlayerClientProvider defaultLocale={locale}>
              <body>{children}</body>
            </IntlayerClientProvider>
          </html>
        );
      };
      
      export default RootLayout;
    5. Объявите ваш контент

      Создавайте и управляйте вашими объявлениями контента для хранения переводов:

      src/app/metadata.content.ts
      import { t, type Dictionary } from "intlayer";
      import { Metadata } from "next";
      
      const metadataContent = {
        key: "metadata",
        content: {
          title: t({
            ru: "Заголовок моего проекта",
            en: "My Project Title",
            fr: "Le Titre de mon Projet",
            es: "El Título de mi Proyecto",
          }),
      
          description: t({
            ru: "Ознакомьтесь с нашей инновационной платформой, созданной для оптимизации рабочего процесса и повышения продуктивности.",
            en: "Discover our innovative platform designed to streamline your workflow and boost productivity.",
            ru: "Откройте для себя нашу инновационную платформу, созданную для оптимизации рабочего процесса и повышения продуктивности.",
            fr: "Découvrez notre plateforme innovante conçue pour simplifier votre flux de travail et booster votre productivité.",
            es: "Descubra su plataforma innovadora diseñada para simplificar su flujo de trabajo y aumentar su productividad.",
          }),
      
          keywords: t({
            ru: ["инновации", "продуктивность", "рабочий процесс", "SaaS"],
            en: ["innovation", "productivity", "workflow", "SaaS"],
            fr: ["innovation", "productivité", "flux de travail", "SaaS"],
            es: ["innovación", "productividad", "flujo de trabajo", "SaaS"],
          }),
        },
      } as Dictionary<Metadata>;
      
      export default metadataContent;
      src/app/page.content.ts
      import { t, type Dictionary } from "intlayer";
      
      const pageContent = {
        key: "page",
        content: {
          getStarted: {
            main: t({
              ru: "Начните с редактирования",
              en: "Get started by editing",
              fr: "Commencez par éditer",
              es: "Comience por editar",
            }),
            pageLink: "src/app/page.tsx",
          },
        },
      } satisfies Dictionary;
      
      export default pageContent;
      Ваши объявления контента могут быть определены в любом месте вашего приложения, при условии что они включены в директорию contentDir (по умолчанию ./src). И соответствуют расширению файла объявления контента (по умолчанию .content.{json,ts,tsx,js,jsx,mjs,cjs,md,mdx,yaml,yml}).
      Для получения подробной информации обратитесь к документации по объявлениям контента.
    6. Использование контента в коде

      Получайте доступ к словарям контента по всему приложению:

      src/app/page.tsx
      import type { FC } from "react";
      import { ClientComponentExample } from "@components/clientComponentExample/ClientComponentExample";
      import { ServerComponentExample } from "@components/serverComponentExample/ServerComponentExample";
      import { IntlayerServerProvider, useIntlayer } from "next-intlayer/server";
      import { NextPage } from "next";
      import { getLocale } from "intlayer";
      import { headers, cookies } from "next/headers";
      
      const PageContent: FC = () => {
        const content = useIntlayer("page");
      
        return (
          <>
            <p>{content.getStarted.main}</p>
            <code>{content.getStarted.pageLink}</code>
          </>
        );
      };
      
      const Page: NextPage = async () => {
        // Ожидайте headers и cookies в Next.js 15+
        const headerList = await headers();
        const cookieList = await cookies();
      
        const locale = await getLocale({
          // Сначала проверьте cookie intlayer (по умолчанию: 'INTLAYER_LOCALE')
          getCookie: (name) => cookieList.get(name)?.value,
      
          // Затем проверяем заголовок intlayer (по умолчанию: 'x-intlayer-locale')
          // И, наконец, проверяем заголовок accept-language ('accept-language')
          getHeader: (name) => headerList.get(name),
        });
      
        return (
          <IntlayerServerProvider locale={locale}>
            <PageContent />
            <ServerComponentExample />
            <ClientComponentExample />
          </IntlayerServerProvider>
        );
      };
      
      export default Page;
      • IntlayerClientProvider используется для предоставления locale клиентским компонентам. Его можно разместить в любом родительском компоненте, включая layout. Однако рекомендуется помещать его в layout, потому что Next.js использует общий код layout между страницами, что делает это более эффективным. Используя IntlayerClientProvider в layout, вы избегаете повторной инициализации на каждой странице, повышаете производительность и поддерживаете единый контекст локализации во всём приложении.
      • IntlayerServerProvider используется для предоставления locale серверным дочерним компонентам. Его нельзя установить в layout.
      Layout и page не могут разделять общий server context, потому что система server context основана на хранилище данных, привязанном к каждому запросу (через механизм React's cache), из‑за чего каждый «context» воссоздаётся для разных сегментов приложения. Размещение provider в общем layout нарушит эту изоляцию и помешает корректной передаче значений server context в ваши server components.
      src/components/clientComponentExample/ClientComponentExample.tsx
      "use client";
      
      import type { FC } from "react";
      import { useIntlayer } from "next-intlayer";
      
      export const ClientComponentExample: FC = () => {
        const content = useIntlayer("client-component-example"); // Создаёт соответствующее объявление контента
      
        return (
          <div>
            <h2>{content.title}</h2>
            <p>{content.content}</p>
          </div>
        );
      };
      src/components/serverComponentExample/ServerComponentExample.tsx
      import type { FC } from "react";
      import { useIntlayer } from "next-intlayer/server";
      
      export const ServerComponentExample: FC = () => {
        const content = useIntlayer("server-component-example"); // Создать декларацию связанного контента
      
        return (
          <div>
            <h2>{content.title}</h2>
            <p>{content.content}</p>
          </div>
        );
      };
      Если вы хотите использовать содержимое в строковом атрибуте, таком как alt, title, href, aria-label и т.д., вы должны вызвать значение функции, например:
      html
      <img src="{content.image.src.value}" alt="{content.image.value}" /><img src="{content.image.src.toString()}" alt="{content.image.toString()}" /><img src="{String(content.image.src)}" alt="{String(content.image)}" />
      Чтобы узнать больше о хуке useIntlayer, см. документацию.
    7. Настройка прокси для определения локали

      Необязательно

      Настройте прокси для определения предпочитаемой пользователем локали:

      src/proxy.ts
      export { intlayerProxy as proxy } from "next-intlayer/proxy";
      
      export const config = {
        matcher:
          "/((?!api|static|assets|robots|sitemap|sw|service-worker|manifest|.*\\..*|_next).*)",
      };
      Прокси intlayerProxy используется для определения предпочитаемой локали пользователя и перенаправления его на соответствующий URL, как указано в конфигурации. Кроме того, он позволяет сохранять предпочитаемую локаль пользователя в cookie.
      Если требуется связать несколько прокси вместе (например, intlayerProxy с прокси авторизации или пользовательскими прокси), Intlayer предоставляет вспомогательную функцию multipleProxies.
      ts
      import { multipleProxies, intlayerProxy } from "next-intlayer/proxy";import { customProxy } from "@utils/customProxy";export const proxy = multipleProxies([intlayerProxy, customProxy]);
    8. Изменение языка вашего контента

      Необязательно

      Чтобы изменить язык содержимого в Next.js, рекомендуется использовать компонент Link, чтобы перенаправлять пользователей на соответствующую локализованную страницу. Компонент Link поддерживает предзагрузку страницы (prefetch), что помогает избежать полной перезагрузки страницы.

      src/components/localeSwitcher/LocaleSwitcher.tsx
      "use client";
      
      import type { FC } from "react";
      import { Locales, getHTMLTextDir, getLocaleName } from "intlayer";
      import { useLocale } from "next-intlayer";
      
      export const LocaleSwitcher: FC = () => {
        const { locale, availableLocales, setLocale } = useLocale();
      
        return (
          <div>
            <button popoverTarget="localePopover">{getLocaleName(locale)}</button>
            <div id="localePopover" popover="auto">
              {availableLocales.map((localeItem) => (
                <button
                  key={localeItem}
                  aria-current={locale === localeItem ? "page" : undefined}
                  onClick={() => setLocale(localeItem)}
                >
                  <span>
                    {/* Локаль, например FR */}
                    {localeItem}
                  </span>
                  <span>
                    {/* Название языка в своей локали, например Français */}
                    {getLocaleName(localeItem, locale)}
                  </span>
                  <span dir={getHTMLTextDir(localeItem)} lang={localeItem}>
                    {/* Название языка в текущей локали, например Francés при текущей локали Locales.SPANISH */}
                    {getLocaleName(localeItem)}
                  </span>
                  <span dir="ltr" lang={Locales.ENGLISH}>
                    {/* Название языка на английском, напр., French */}
                    {getLocaleName(localeItem, Locales.ENGLISH)}
                  </span>
                </button>
              ))}
            </div>
          </div>
        );
      };
      Альтернативный способ, использовать функцию setLocale, предоставляемую хуком useLocale. Эта функция не будет позволять предзагружать страницу. См. документацию по хуку useLocale для получения дополнительных сведений.

      Ссылки в документации:

      (Необязательно) Шаг 9: Получить текущую локаль в Server Actions

      Если вам нужна активная локаль внутри Server Action (например, чтобы локализовать письма или выполнить логику, зависящую от локали), вызовите getLocale из next-intlayer/server:

      src/app/actions/getLocale.ts
      "use server";import { getLocale } from "next-intlayer/server";export const myServerAction = async () => {  const locale = await getLocale();  // Выполните действия с локалью};

      Функция getLocale использует каскадную стратегию для определения локали пользователя:

      1. Сначала она проверяет заголовки запроса на наличие значения локали, которое могло быть установлено proxy
      2. Если в заголовках локаль не найдена, она ищет локаль в cookies
      3. Если cookies не найдено, она пытается определить предпочитаемый язык пользователя из настроек браузера
      4. В крайнем случае используется локаль по умолчанию, настроенная в приложении

      Это гарантирует выбор наиболее подходящей локали на основе доступного контекста.

    9. Оптимизируйте размер бандла

      Необязательно

      При использовании next-intlayer словари по умолчанию включаются в бандл для каждой страницы. Чтобы оптимизировать размер бандла, Intlayer предоставляет опциональный SWC-плагин, который интеллектуально заменяет вызовы useIntlayer с помощью макросов. Это гарантирует, что словари будут включаться в бандлы только для тех страниц, которые действительно их используют.

      Чтобы включить эту оптимизацию, установите пакет @intlayer/swc. После установки next-intlayer автоматически обнаружит и начнёт использовать плагин:

      bash
      npm install @intlayer/swc --save-dev
      Примечание: Эта оптимизация доступна только для Next.js 13 и выше.
      Примечание: Этот пакет не устанавливается по умолчанию, поскольку SWC-плагины в Next.js всё ещё экспериментальны. Это может измениться в будущем.

      Примечание: Если установить опцию как importMode: 'dynamic' или importMode: 'fetch' (in the dictionary configuration), будет полагаться на Suspense, поэтому вам придётся оборачивать вызовы useIntlayer в границу Suspense. Это означает, что вы не сможете использовать useIntlayer прямо на верхнем уровне вашего компонента Page / Layout.

    Отслеживание изменений словарей в Turbopack

    Когда вы используете Turbopack в качестве сервера разработки с командой next dev, изменения словарей по умолчанию не будут автоматически обнаруживаться.

    Это ограничение возникает из-за того, что Turbopack не может параллельно запускать плагины webpack для отслеживания изменений в ваших файлах с содержимым. Чтобы обойти это, вам нужно использовать команду intlayer watch, чтобы одновременно запустить сервер разработки и наблюдатель сборки Intlayer.

    package.json
    {  // ... Ваши существующие настройки package.json  "scripts": {    // ... Ваши существующие конфигурации скриптов    "dev": "intlayer watch --with 'next dev'",  },}
    Если вы используете next-intlayer@<=6.x.x, необходимо сохранять флаг --turbopack, чтобы приложение Next.js 16 корректно работало с Turbopack. Рекомендуем использовать next-intlayer@>=7.x.x, чтобы избежать этого ограничения.

    Настройка TypeScript

    Intlayer использует module augmentation, чтобы получить преимущества TypeScript и укрепить вашу codebase.

    Автодополнение

    Ошибка перевода

    Убедитесь, что конфигурация TypeScript включает автогенерируемые типы.

    tsconfig.json
    {  // ... Ваши существующие конфигурации TypeScript  "include": [    // ... Ваши существующие конфигурации TypeScript    ".intlayer/**/*.ts", // Включить автоматически сгенерированные типы  ],}

    Конфигурация Git

    Рекомендуется игнорировать файлы, сгенерированные Intlayer. Это позволяет избежать их добавления в ваш Git-репозиторий.

    Для этого вы можете добавить следующие инструкции в файл .gitignore:

    .gitignore
    # Игнорировать файлы, сгенерированные Intlayer.intlayer

    Расширение VS Code

    Чтобы улучшить опыт разработки с Intlayer, вы можете установить официальное Intlayer VS Code Extension.

    Установить из VS Code Marketplace

    Это расширение предоставляет:

    • Автодополнение для ключей переводов.
    • Обнаружение ошибок в реальном времени для отсутствующих переводов.
    • Встроенные превью переведённого контента.
    • Быстрые действия для простого создания и обновления переводов.

    Для получения подробной информации о том, как использовать расширение, обратитесь к документации Intlayer VS Code Extension.

    Продвинутые возможности

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