ГлавнаяПесочницаВитринаПриложениеДокументБлог
    • Englishанглийский
      EN
    • русскийрусский
      RU
    • 日本語японский
      JA
    • françaisфранцузский
      FR
    • 한국어корейский
      KO
    • 中文китайский
      ZH
    • españolиспанский
      ES
    • Deutschнемецкий
      DE
    • العربيةарабский
      AR
    • italianoитальянский
      IT
    • British Englishбританский английский
      EN-GB
    • portuguêsпортугальский
      PT
    • हिन्दीхинди
      HI
    • Türkçeтурецкий
      TR
    • polskiпольский
      PL
    • Indonesiaиндонезийский
      ID
    • Tiếng Việtвьетнамский
      VI
    • українськаукраинский
      UK
    /
    Фильтровать документы по фреймворку
    Alt+←
    Почему Intlayer?
    Начать
    Концепция
    • Как работает Intlayer
    • Конфигурация
    • TestFillBuildWatchExtractLoginPushPullConfigurationListVersionEditorLiveDebugDoc ReviewDoc TranslateSDK
    • Визуальный редактор
    • CMS
    • Интеграция CI/CD
    • ПереводМножественное числоПеречислениеУсловиеПолВставкаФайлВложенностьMarkdownHTMLПолучение функции
    • Файл для каждой локали
    • Компилятор
    • Автозаполнение
    • Тестирование
    • Оптимизация пакета
    Окружающая среда
    • Next.js 14 и App Router
      Next.js 15
      Next.js без locale URL
      Next.js и Page Router
      Compiler
    • Tanstack Start Solid
    • Astro и React
      Astro и Svelte
      Astro и Vue
      Astro и Solid
      Astro и Preact
      Astro и Lit
      Astro и Vanilla JS
    • React Router v7
      React Router v7 (fs-routes)
      Compiler
    • Nuxt и Vue
    • Vite и Solid
    • SvelteKit
    • Vite и Preact
    • Vite и Vanilla JS
    • Vite и Lit
    • Angular 19 (Webpack)
      Analog
    • React CRA
    • React Native и Expo
    • Express.js
      NestJS
      Fastify
      Hono
      Adonis
    • Lynx и React
    Plugins
    • JSON
    • gettext (.po)
    Расширение VS Code
    Агент
    • Сервер MCP
    • Навики агента
    Релизы
    • v8
    • v7
    • v6
    Бенчмарк
    • Next.js
    • TanStack
    • Vue
    • Solid
    • Svelte
    Блог
    Задать вопрос
    1. Documentation
    2. Окружающая среда
    3. Next.js
    Создание:2024-12-06Последнее обновление:2026-05-06
    Посмотреть шаблон приложения на GitHub

    Для этой страницы доступен шаблон приложения.

    Посмотреть демонстрационное приложение

    Эта страница ведёт на живую демонстрацию шаблона.

    Посмотреть видео урок

    Для этой страницы доступен видео урок.

    Ссылайтесь на этот документ на ваш любимый ассистент AI
    ChatGPT
    Claude
    DeepSeek
    Google AI mode
    Gemini
    Perplexity
    Mistral
    Grok

    Спросите свой вопрос и получите сводку документа, используя эту страницу и выбранного вами поставщика AI

    История версий

    1. "Обновление использования API useIntlayer в Solid для прямого доступа к свойствам"
      v8.9.004.05.2026
    2. "Добавить команду init"
      v7.5.930.12.2025
    3. "Добавлено упоминание `x-default` в объекте `alternates`"
      v7.0.601.11.2025
    4. "Инициализация истории"
      v7.0.029.06.2025

    Содержимое этой страницы было переведено с помощью ИИ.

    Смотреть последнюю версию оригинального контента на английском
    Изменить эту документацию

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

    Ссылка на документацию GitHub
    Копировать

    Копировать Markdown документа в буфер обмена

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

    www.youtube.com
    ide.intlayer.org
    intlayer-next-16-template.vercel.app

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

    Содержание

    Что такое Intlayer?

    Intlayer, это инновационная, открытая библиотека интернационализации (i18n), разработанная для упрощения поддержки многоязычности в современных веб-приложениях. Intlayer бесшовно интегрируется с последним фреймворком Next.js 16, включая его мощный App Router. Она оптимизирована для работы с Server Components для эффективного рендеринга и полностью совместима с Turbopack.

    С помощью Intlayer вы можете:

    • Легко управлять переводами с использованием декларативных словарей на уровне компонентов.
    • Динамически локализовать метаданные, маршруты и контент.
    • Получать доступ к переводам как в клиентских, так и в серверных компонентах.
    • Обеспечить поддержку TypeScript с автогенерируемыми типами, улучшая автодополнение и обнаружение ошибок.
    • Воспользоваться расширенными возможностями, такими как динамическое определение и переключение локали.

    Intlayer совместим с Next.js 12, 13, 14 и 16. Если вы используете Next.js Page Router, вы можете обратиться к этому руководству. Локальный роутинг полезен для SEO, размера бандла и производительности. Если он вам не нужен, вы можете обратиться к этому руководству. Для Next.js 12, 13, 14 с App Router обратитесь к этому руководству.


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

    Шаг 1: Установка зависимостей

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

    bash
    Копировать код

    Копировать код в буфер обмена

    npm install intlayer next-intlayernpx intlayer init
    • intlayer

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

    • next-intlayer

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

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

    Вот окончательная структура, которую мы создадим:

    bash
    Копировать код

    Копировать код в буфер обмена

    .├── src│   ├── app│   │   ├── [locale]│   │   │   ├── layout.tsx            # Локальный макет для провайдера Intlayer│   │   │   ├── page.content.ts│   │   │   └── page.tsx│   │   └── layout.tsx                # Корневой макет для стилей и глобальных провайдеров│   ├── components│   │   ├── client-component-example.content.ts│   │   ├── ClientComponentExample.tsx│   │   ├── LocaleSwitcher│   │   │   ├── localeSwitcher.content.ts│   │   │   └── LocaleSwitcher.tsx│   │   ├── server-component-example.content.ts│   │   └── ServerComponentExample.tsx│   └── proxy.ts├── intlayer.config.ts├── next.config.ts├── package.json└── tsconfig.json
    Если вы не хотите использовать локальный роутинг, intlayer можно использовать как простой провайдер / хук. Смотрите это руководство для получения подробной информации.

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

    intlayer.config.ts
    Копировать код

    Копировать код в буфер обмена

    import { Locales, type IntlayerConfig } from "intlayer";
    
    const config: IntlayerConfig = {
      internationalization: {
        locales: [
          Locales.ENGLISH,
          Locales.FRENCH,
          Locales.SPANISH,
          // Ваши другие локали
        ],
        defaultLocale: Locales.ENGLISH,
      },
    };
    
    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() является асинхронной функцией. Она позволяет подготовить словари 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 { PropsWithChildren, FC } from "react";
    import "./globals.css";
    
    const RootLayout: FC<PropsWithChildren> = ({ children }) => (
      // Вы всё ещё можете обернуть children в другие провайдеры, такие как `next-themes`, `react-query`, `framer-motion` и т.д.
      <>{children}</>
    );
    
    export default RootLayout;
    Оставляя компонент RootLayout пустым, вы позволяете установить атрибуты lang и dir для тега <html>.

    Для реализации динамической маршрутизации укажите путь для локали, добавив новый макет в ваш каталог [locale]:

    src/app/[locale]/layout.tsx
    Копировать код

    Копировать код в буфер обмена

    import { type NextLayoutIntlayer, IntlayerClientProvider } from "next-intlayer";
    import { Inter } from "next/font/google";
    import { getHTMLTextDir } from "intlayer";
    
    const inter = Inter({ subsets: ["latin"] });
    
    const LocaleLayout: NextLayoutIntlayer = async ({ children, params }) => {
      const { locale } = await params;
      return (
        <html lang={locale} dir={getHTMLTextDir(locale)}>
          <body className={inter.className}>
            <IntlayerClientProvider locale={locale}>
              {children}
            </IntlayerClientProvider>
          </body>
        </html>
      );
    };
    
    export default LocaleLayout;
    Сегмент пути [locale] используется для определения локали. Пример: /en-US/about будет соответствовать en-US, а /fr/about, fr.
    На этом этапе вы столкнетесь с ошибкой: Error: Missing <html> and <body> tags in the root layout.. Это ожидаемо, так как файл /app/page.tsx больше не используется и может быть удален. Вместо этого сегмент пути [locale] активирует страницу /app/[locale]/page.tsx. Следовательно, страницы будут доступны по путям, таким как /en, /fr, /es в вашем браузере. Чтобы установить локаль по умолчанию как корневую страницу, обратитесь к настройке proxy в шаге 7.

    Затем реализуйте функцию generateStaticParams в макете вашего приложения.

    src/app/[locale]/layout.tsx
    Копировать код

    Копировать код в буфер обмена

    export { generateStaticParams } from "next-intlayer"; // Строка для вставки
    
    const LocaleLayout: NextLayoutIntlayer = async ({ children, params }) => {
      /*... Остальная часть кода*/
    };
    
    export default LocaleLayout;
    generateStaticParams гарантирует, что ваше приложение предварительно собирает необходимые страницы для всех локалей, уменьшая вычисления во время выполнения и улучшая пользовательский опыт. Для получения дополнительной информации обратитесь к документации Next.js по generateStaticParams.
    Intlayer работает с export const dynamic = 'force-static';, чтобы обеспечить предварительную сборку страниц для всех локалей.

    Шаг 5: Объявите ваш контент

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

    src/app/[locale]/page.content.ts
    Копировать код

    Копировать код в буфер обмена

    import { t, type Dictionary } from "intlayer";
    
    const pageContent = {
      key: "page",
      content: {
        getStarted: {
          main: t({
            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}).
    Для получения дополнительной информации обратитесь к документации по объявлениям контента.

    Шаг 6: Использование контента в вашем коде

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

    src/app/[locale]/page.tsx
    Копировать код

    Копировать код в буфер обмена

    import type { FC } from "react";
    import { ClientComponentExample } from "@components/ClientComponentExample";
    import { ServerComponentExample } from "@components/ServerComponentExample";
    import { type NextPageIntlayer } from "next-intlayer";
    import { IntlayerServerProvider, useIntlayer } from "next-intlayer/server";
    
    const PageContent: FC = () => {
      const content = useIntlayer("page");
    
      return (
        <>
          <p>{content.getStarted.main}</p>
          <code>{content.getStarted.pageLink}</code>
        </>
      );
    };
    
    const Page: NextPageIntlayer = async ({ params }) => {
      const { locale } = await params;
    
      return (
        <IntlayerServerProvider locale={locale}>
          <PageContent />
          <ServerComponentExample />
    
          <ClientComponentExample />
        </IntlayerServerProvider>
      );
    };
    
    export default Page;
    • IntlayerClientProvider используется для предоставления локали компонентам на стороне клиента. Его можно разместить в любом родительском компоненте, включая макет. Однако рекомендуется размещать его в макете, так как Next.js разделяет код макета между страницами, что делает это более эффективным. Используя IntlayerClientProvider в макете, вы избегаете повторной инициализации для каждой страницы, улучшая производительность и поддерживая единый контекст локализации во всем приложении.
    • IntlayerServerProvider используется для предоставления локали дочерним компонентам на сервере. Его нельзя устанавливать в макете.

      Макет и страница не могут использовать общий серверный контекст, поскольку система серверного контекста основана на хранилище данных для каждого запроса (через механизм React's cache), из-за чего каждый "контекст" создаётся заново для разных сегментов приложения. Размещение провайдера в общем макете нарушит эту изоляцию, препятствуя правильной передаче значений серверного контекста вашим серверным компонентам.
    src/components/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.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>
      );
    };
    Если вы хотите использовать ваш контент в атрибуте типа string, таком как 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, обратитесь к документации.
    Если ваше приложение уже существует, вы можете использовать Intlayer Compiler в сочетании с командой extract, чтобы преобразовать тысячи компонентов за одну секунду.

    (Необязательно) Шаг 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: Интернационализация ваших метаданных

    Если вы хотите интернационализировать ваши метаданные, такие как заголовок вашей страницы, вы можете использовать функцию generateMetadata, предоставляемую Next.js. Внутри вы можете получить содержимое из функции getIntlayer для перевода ваших метаданных.

    src/app/[locale]/metadata.content.ts
    Копировать код

    Копировать код в буфер обмена

    import { type Dictionary, t } from "intlayer";
    import { Metadata } from "next";
    
    const metadataContent = {
      key: "page-metadata",
      content: {
        title: t({
          en: "Create Next App",
          fr: "Créer une application Next.js",
          es: "Crear una aplicación Next.js",
        }),
        description: t({
          en: "Generated by create next app",
          fr: "Généré par create next app",
          es: "Generado por create next app",
        }),
      },
    } satisfies Dictionary<Metadata>;
    
    export default metadataContent;
    src/app/[locale]/layout.tsx or src/app/[locale]/page.tsx
    Копировать код

    Копировать код в буфер обмена

    import { getIntlayer, getMultilingualUrls } from "intlayer";
    import type { Metadata } from "next";
    import type { LocalPromiseParams } from "next-intlayer";
    
    export const generateMetadata = async ({
      params,
    }: LocalPromiseParams): Promise<Metadata> => {
      const { locale } = await params;
    
      const metadata = getIntlayer("page-metadata", locale);
    
      /**
       * Генерирует объект, содержащий все URL для каждой локали.
       *
       * Пример:
       * ```ts
       *  getMultilingualUrls('/about');
       *
       *  // Возвращает
       *  // {
       *  //   en: '/about',
       *  //   fr: '/fr/about',
       *  //   es: '/es/about',
       *  // }
       * ```
       */
      const multilingualUrls = getMultilingualUrls("/");
      const localizedUrl =
        multilingualUrls[locale as keyof typeof multilingualUrls];
    
      return {
        ...metadata,
        alternates: {
          canonical: localizedUrl,
          languages: { ...multilingualUrls, "x-default": "/" },
        },
        openGraph: {
          url: localizedUrl,
        },
      };
    };
    
    // ... Остальная часть кода
    Обратите внимание, что функция getIntlayer, импортируемая из next-intlayer, возвращает ваш контент, обёрнутый в IntlayerNode, что позволяет интегрироваться с визуальным редактором. В то время как функция getIntlayer, импортируемая из intlayer, возвращает ваш контент напрямую без дополнительных свойств.

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

    src/app/[locale]/layout.tsx or src/app/[locale]/page.tsx
    Копировать код

    Копировать код в буфер обмена

    import {
      type IConfigLocales,
      getTranslation,
      getMultilingualUrls,
    } from "intlayer";
    import type { Metadata } from "next";
    import type { LocalPromiseParams } from "next-intlayer";
    
    export const generateMetadata = async ({
      params,
    }: LocalPromiseParams): Promise<Metadata> => {
      const { locale } = await params;
      const t = <T>(content: IConfigLocales<T>) => getTranslation(content, locale);
    
      return {
        title: t<string>({
          en: "My title",
          fr: "Mon titre",
          es: "Mi título",
        }),
        description: t({
          en: "My description",
          fr: "Ma description",
          es: "Mi descripción",
        }),
      };
    };
    
    // ... Остальная часть кода
    Узнайте больше об оптимизации метаданных в официальной документации Next.js.

    (Необязательно) Шаг 9: Интернационализация ваших sitemap.xml и robots.txt

    Чтобы интернационализировать ваши sitemap.xml и robots.txt, вы можете использовать функцию getMultilingualUrls, предоставляемую Intlayer. Эта функция позволяет генерировать многоязычные URL-адреса для вашей карты сайта.

    src/app/sitemap.ts
    Копировать код

    Копировать код в буфер обмена

    import { getMultilingualUrls } from "intlayer";
    import type { MetadataRoute } from "next";
    
    const sitemap = (): MetadataRoute.Sitemap => [
      {
        url: "https://example.com",
        alternates: {
          languages: {
            ...getMultilingualUrls("https://example.com"),
            "x-default": "https://example.com",
          },
        },
      },
      {
        url: "https://example.com/login",
        alternates: {
          languages: {
            ...getMultilingualUrls("https://example.com/login"),
            "x-default": "https://example.com/login",
          },
        },
      },
      {
        url: "https://example.com/register",
        alternates: {
          languages: {
            ...getMultilingualUrls("https://example.com/register"),
            "x-default": "https://example.com/register",
          },
        },
      },
    ];
    
    export default sitemap;
    src/app/robots.ts
    Копировать код

    Копировать код в буфер обмена

    import type { MetadataRoute } from "next";
    import { getMultilingualUrls } from "intlayer";
    
    const getAllMultilingualUrls = (urls: string[]) =>
      urls.flatMap((url) => Object.values(getMultilingualUrls(url)) as string[]);
    
    const robots = (): MetadataRoute.Robots => ({
      rules: {
        userAgent: "*",
        allow: ["/"],
        disallow: getAllMultilingualUrls(["/login", "/register"]),
      },
      host: "https://example.com",
      sitemap: `https://example.com/sitemap.xml`,
    });
    
    export default robots;
    Узнайте больше об оптимизации карты сайта в официальной документации Next.js. Узнайте больше об оптимизации robots.txt в официальной документации Next.js.

    (Необязательно) Шаг 10: Изменение языка вашего контента

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

    src/components/LocaleSwitcher.tsx
    Копировать код

    Копировать код в буфер обмена

    "use client";
    
    import type { FC } from "react";
    import {
      Locales,
      getHTMLTextDir,
      getLocaleName,
      getLocalizedUrl,
    } from "intlayer";
    import { useLocale } from "next-intlayer";
    import Link from "next/link";
    
    export const LocaleSwitcher: FC = () => {
      const { locale, pathWithoutLocale, availableLocales, setLocale } =
        useLocale();
    
      return (
        <div>
          <button popoverTarget="localePopover">{getLocaleName(locale)}</button>
          <div id="localePopover" popover="auto">
            {availableLocales.map((localeItem) => (
              <Link
                href={getLocalizedUrl(pathWithoutLocale, localeItem)}
                key={localeItem}
                aria-current={locale === localeItem ? "page" : undefined}
                onClick={() => setLocale(localeItem)}
                replace // Будет гарантировать, что кнопка "назад" в браузере перенаправит на предыдущую страницу
              >
                <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>
              </Link>
            ))}
          </div>
        </div>
      );
    };
    Альтернативным способом является использование функции setLocale, предоставляемой хуком useLocale. Эта функция не позволяет предварительно загружать страницу. См. документацию хука useLocale для получения подробной информации.
    Вы также можете установить функцию в опции onLocaleChange, чтобы вызвать пользовательскую функцию при изменении локали.
    src/components/LocaleSwitcher.tsx
    Копировать код

    Копировать код в буфер обмена

    "use client";import { useRouter } from "next/navigation";import { useLocale } from "next-intlayer";import { getLocalizedUrl } from "intlayer";// ... Остальная часть кодаconst router = useRouter();const { setLocale } = useLocale({  onLocaleChange: (locale) => {    router.push(getLocalizedUrl(pathWithoutLocale, locale));  },});return (  <button onClick={() => setLocale(Locales.FRENCH)}>    Переключить на французский  </button>);

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

    • хук useLocale
    • хук getLocaleName
    • хук getLocalizedUrl
    • хук getHTMLTextDir
    • атрибут hrefLang
    • атрибут lang
    • атрибут dir
    • атрибут aria-current

    (Необязательно) Шаг 11: Создание локализованного компонента Link

    Чтобы навигация вашего приложения соответствовала текущей локали, вы можете создать кастомный компонент Link. Этот компонент автоматически добавляет префикс текущего языка к внутренним URL-адресам. Например, когда франкоязычный пользователь нажимает на ссылку "О нас", он перенаправляется на /fr/about вместо /about.

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

    • SEO и пользовательский опыт: Локализованные URL-адреса помогают поисковым системам правильно индексировать страницы на определенных языках и предоставляют пользователям контент на их предпочтительном языке.
    • Согласованность: Используя локализованную ссылку во всем приложении, вы гарантируете, что навигация остается в пределах текущей локали, предотвращая неожиданные переключения языков.
    • Поддержка: Централизация логики локализации в одном компоненте упрощает управление URL-адресами, делая ваш код более простым в поддержке и расширении по мере роста вашего приложения.

    Ниже приведена реализация локализованного компонента Link на TypeScript:

    src/components/Link.tsx
    Копировать код

    Копировать код в буфер обмена

    "use client";
    
    import { getLocalizedUrl } from "intlayer";
    import NextLink, { type LinkProps as NextLinkProps } from "next/link";
    import { useLocale } from "next-intlayer";
    import type { PropsWithChildren, FC } from "react";
    
    /**
     * Вспомогательная функция для проверки, является ли данный URL внешним.
     * Если URL начинается с http:// или https://, он считается внешним.
     */
    export const checkIsExternalLink = (href?: string): boolean =>
      /^https?:\/\//.test(href ?? "");
    
    /**
     * Кастомный компонент Link, который адаптирует атрибут href в зависимости от текущей локали.
     * Для внутренних ссылок он использует `getLocalizedUrl` для добавления префикса локали к URL (например, /fr/about).
     * Это гарантирует, что навигация остается в контексте той же локали.
     */
    export const Link: FC<PropsWithChildren<NextLinkProps>> = ({
      href,
      children,
      ...props
    }) => {
      const { locale } = useLocale();
      const isExternalLink = checkIsExternalLink(href.toString());
    
      // Если ссылка внутренняя и указан валидный href, получаем локализованный URL.
      const hrefI18n: NextLinkProps["href"] =
        href && !isExternalLink ? getLocalizedUrl(href.toString(), locale) : href;
    
      return (
        <NextLink href={hrefI18n} {...props}>
          {children}
        </NextLink>
      );
    };

    Как это работает

    • Определение внешних ссылок:
      Вспомогательная функция checkIsExternalLink определяет, является ли URL внешним. Внешние ссылки остаются без изменений, так как они не требуют локализации.

    • Получение текущей локали:
      Хук useLocale предоставляет текущую локаль (например, fr для французского).

    • Локализация URL:
      Для внутренних ссылок (т. е. не внешних) используется getLocalizedUrl для автоматического добавления префикса текущей локали к URL. Это означает, что если ваш пользователь находится на французской версии сайта, передача /about в качестве href преобразует его в /fr/about.

    • Возврат ссылки:
      Компонент возвращает элемент <a> с локализованным URL, обеспечивая соответствие навигации локали.

    Интегрируя этот компонент Link во все приложение, вы поддерживаете согласованный и учитывающий язык пользовательский интерфейс, а также извлекаете выгоду из улучшенного SEO и удобства использования.

    (Необязательно) Шаг 12: Получение текущей локали в 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. Сначала она проверяет заголовки запроса на наличие значения локали, которое могло быть установлено прокси.
    2. Если локаль не найдена в заголовках, она ищет локаль, сохраненную в куки.
    3. Если куки не найдены, она пытается определить предпочтительный язык пользователя по настройкам его браузера.
    4. В крайнем случае она возвращается к настроенной в приложении локали по умолчанию.

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

    (Необязательно) Шаг 13: Оптимизация размера вашего бандла

    При использовании 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' (в конфигурации dictionary), она будет полагаться на 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 и сделать вашу кодовую базу более надежной.

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

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

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

    tsconfig.json
    Копировать код

    Копировать код в буфер обмена

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

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

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

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

    .gitignore
    Копировать код

    Копировать код в буфер обмена

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

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

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

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

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

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

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

    (Опционально) Шаг 1 : Извлечение содержимого ваших компонентов

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

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

    Чтобы настроить его, вы можете добавить раздел compiler в ваш файл intlayer.config.ts:

    intlayer.config.ts
    Копировать код

    Копировать код в буфер обмена

    import { type IntlayerConfig } from "intlayer";
    
    const config: IntlayerConfig = {
      // ... Остальная часть вашей конфигурации
      compiler: {
        /**
         * Указывает, должен ли быть включен компилятор.
         */
        enabled: true,
    
        /**
         * Определяет путь к выходным файлам
         */
        output: ({ fileName, extension }) => `./${fileName}${extension}`,
    
        /**
         * Указывает, должны ли компоненты сохраняться после преобразования. Таким образом, компилятор можно запустить только один раз для преобразования приложения, а затем удалить.
         */
        saveComponents: false,
    
        /**
         * Префикс ключа словаря
         */
        dictionaryKeyPrefix: "",
      },
    };
    
    export default config;

    Запустите экстрактор для преобразования компонентов и извлечения содержимого

    bash
    Копировать код

    Копировать код в буфер обмена

    npx intlayer extract
    bash
    Копировать код

    Копировать код в буфер обмена

    npm install @intlayer/babel --save-dev
    babel.config.js
    Копировать код

    Копировать код в буфер обмена

    const { intlayerExtractBabelPlugin, getExtractPluginOptions,} = require("@intlayer/babel");module.exports = { presets: ["next/babel"], plugins: [   // Извлечение содержимого из компонентов в словари   [intlayerExtractBabelPlugin, getExtractPluginOptions()], ],};
    bash
    Копировать код

    Копировать код в буфер обмена

    npm run build # Или npm run dev

    Идите дальше

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

    Оптимизация пакета
    Next.js 14 и App Router
    Alt+→

    На этой странице

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

      npm install intlayer next-intlayernpx intlayer init
      .├── src│   ├── app│   │   ├── [locale]│   │   │   ├── layout.tsx            # Локальный макет для провайдера Intlayer│   │   │   ├── page.content.ts│   │   │   └── page.tsx│   │   └── layout.tsx                # Корневой макет для стилей и глобальных провайдеров│   ├── components│   │   ├── client-component-example.content.ts│   │   ├── ClientComponentExample.tsx│   │   ├── LocaleSwitcher│   │   │   ├── localeSwitcher.content.ts│   │   │   └── LocaleSwitcher.tsx│   │   ├── server-component-example.content.ts│   │   └── ServerComponentExample.tsx│   └── proxy.ts├── intlayer.config.ts├── next.config.ts├── package.json└── tsconfig.json
      const nextConfig = await withIntlayer(nextConfig);const nextConfigWithOtherPlugins = withOtherPlugins(nextConfig);export default nextConfigWithOtherPlugins;
      const nextConfig = withIntlayerSync(nextConfig);const nextConfigWithOtherPlugins = withOtherPlugins(nextConfig);export default nextConfigWithOtherPlugins;
      withRspack(withIntlayer(nextConfig, { enableTurbopack: false }));
      <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)}" />
      import { multipleProxies, intlayerProxy } from "next-intlayer/proxy";import { customProxy } from "@utils/customProxy";export const proxy = multipleProxies([intlayerProxy, customProxy]);
      "use client";import { useRouter } from "next/navigation";import { useLocale } from "next-intlayer";import { getLocalizedUrl } from "intlayer";// ... Остальная часть кодаconst router = useRouter();const { setLocale } = useLocale({  onLocaleChange: (locale) => {    router.push(getLocalizedUrl(pathWithoutLocale, locale));  },});return (  <button onClick={() => setLocale(Locales.FRENCH)}>    Переключить на французский  </button>);
      "use server";import { getLocale } from "next-intlayer/server";export const myServerAction = async () => {  const locale = await getLocale();  // Сделайте что-нибудь с локалью};
      npm install @intlayer/swc --save-dev
      {  // ... Ваши существующие конфигурации package.json  "scripts": {    // ... Ваши существующие конфигурации скриптов    "dev": "intlayer watch --with 'next dev'",  },}
      {  // ... Ваши существующие конфигурации TypeScript  "include": [    // ... Ваши существующие конфигурации TypeScript    ".intlayer/**/*.ts", // Включить автоматически сгенерированные типы  ],}
      # Игнорировать файлы, созданные Intlayer.intlayer
      npx intlayer extract
      npm install @intlayer/babel --save-dev
      const { intlayerExtractBabelPlugin, getExtractPluginOptions,} = require("@intlayer/babel");module.exports = { presets: ["next/babel"], plugins: [   // Извлечение содержимого из компонентов в словари   [intlayerExtractBabelPlugin, getExtractPluginOptions()], ],};
      npm run build # Или npm run dev