Creation:2025-10-25Last update:2026-05-31

    Перекладіть ваш вебсайт Next.js 15 за допомогою Intlayer | Інтернаціоналізація (i18n)

    Зміст

    Чому варто обрати Intlayer, а не альтернативи?

    Порівняно з основними рішеннями, такими як next-intl або i18next, Intlayer — це рішення, яке має такі інтегровані оптимізації, як:

    Intlayer оптимізовано для роботи з компонентами сервера для ефективного відтворення та повністю сумісно з Turbopack. Він не блокує статичний рендеринг і пропонує проміжне програмне забезпечення, а також усі функції, необхідні для інтернаціоналізації масштабування (i18n).

    Intlayer сумісний із Next.js 12, 13, 14, 15 і 16. Якщо ви використовуєте маршрутизатор сторінок Next.js, ви можете переглянути цей посібник. Локальна маршрутизація корисна для SEO, розміру пакета та продуктивності. Якщо він вам не потрібен, ви можете звернутися до цього посібника. Щодо Next.js 12, 13, 14 і 15 із маршрутизатором програм див. цей посібник.

    Замість того, щоб завантажувати великі файли JSON на свої сторінки, завантажуйте лише необхідний вміст. Intlayer допомагає зменшити розмір бандлу і сторінок до 50%.

    Організація вмісту за окремими областями (scoping) полегшує технічне обслуговування великомасштабних програм. Ви можете скопіювати або видалити окрему папку функцій без розумового навантаження перегляду всієї кодової бази вмісту. Крім того, Intlayer повністю типізований (fully typed), щоб забезпечити точність вашого вмісту.

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

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

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

    Більше ніж просто рішення i18n, Intlayer пропонує власний візуальний редактор і повний CMS, щоб допомогти вам керувати своїм багатомовним вмістом у реальному часі, спрощуючи співпрацю з перекладачами, копірайтерами та іншими членами команди. Контент можна зберігати локально та/або віддалено.


    Покроковий посібник з налаштування Intlayer у додатку Next.js

    www.youtube.com

    Дивіться Application Template на GitHub.

    1. Встановлення залежностей

      Встановіть необхідні пакети за допомогою npm:

      bash
      npm install intlayer next-intlayernpx intlayer init
      • intlayer

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

      • next-intlayer

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

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

      • next-intlayer

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

    2. Налаштуйте свій проєкт

      Here is the final structure that we will make:

      bash
      .├── src│   ├── app│   │   ├── [locale]│   │   │   ├── layout.tsx            # Locale layout for the Intlayer provider│   │   │   ├── page.content.ts│   │   │   └── page.tsx│   │   └── layout.tsx                # Root layout for style and global providers│   ├── components│   │   ├── client-component-example.content.ts│   │   ├── ClientComponentExample.tsx│   │   ├── LocaleSwitcher│   │   │   ├── localeSwitcher.content.ts│   │   │   └── LocaleSwitcher.tsx│   │   ├── server-component-example.content.ts│   │   └── ServerComponentExample.tsx│   └── middleware.ts├── intlayer.config.ts├── next.config.ts├── package.json└── tsconfig.json
      If you don't want locale routing, intlayer can be used as a simple provider / hook. See this guide for more details.

      Створіть файл конфігурації, щоб налаштувати мови вашого застосунку:

      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-адреси, перенаправлення через middleware, назви 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. Додатково він надає aliases для оптимізації продуктивності та забезпечує сумісність із серверними компонентами.

      Функція withIntlayer() повертає проміс. Вона дозволяє підготувати словники Intlayer перед початком збірки. Якщо ви хочете використовувати її з іншими плагінами, ви можете використати await. Приклад:

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

      Якщо ви хочете використовувати його синхронно, ви можете скористатися функцією withIntlayerSync(). Приклад:

      tsx
      const nextConfig = withIntlayerSync(nextConfig);const nextConfigWithOtherPlugins = withOtherPlugins(nextConfig);export default nextConfigWithOtherPlugins;
    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>.

      Щоб реалізувати динамічну маршрутизацію, вкажіть шлях для локалі, додавши новий layout у ваш каталог [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 у вашому браузері. Щоб встановити локаль за замовчуванням для кореневої сторінки, зверніться до налаштування middleware у кроці 7.

      Далі реалізуйте функцію generateStaticParams у Layout вашого застосунку.

      src/app/[locale]/layout.tsx
      export { generateStaticParams } from "next-intlayer"; // Line to insert
      
      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({
              uk: "Почніть із редагування",
              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/[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 використовується для передачі локалі клієнтським компонентам. Його можна розмістити в будь-якому батьківському компоненті, включно з layout. Однак рекомендовано розміщувати його в layout, оскільки Next.js ділиться кодом layout між сторінками, що робить це ефективнішим. Використовуючи IntlayerClientProvider у layout, ви уникаєте повторної ініціалізації для кожної сторінки, покращуєте продуктивність і підтримуєте послідовний контекст локалізації у всьому вашому додатку.
      • IntlayerServerProvider використовується для надання локалі серверним дочірнім компонентам. Його не можна встановлювати в layout.

        Layout і сторінка не можуть спільно використовувати спільний server context, оскільки система server context базується на сховищі даних для кожного запиту (через механізм React's cache), що призводить до повторного створення кожного "контексту" для різних сегментів додатку. Розміщення провайдера в загальному layout порушить цю ізоляцію і не дозволить правильно передавати значення server context вашим server components.
        Layout і page не можуть мати спільного server context, оскільки система server context базується на сховищі даних на запит (через механізм React's cache), внаслідок чого кожен «context» створюється заново для різних сегментів застосунку. Розміщення провайдера в спільному layout порушило б цю ізоляцію й не дозволило б коректно пропагувати значення server context до ваших server components.
      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, див. документацію.
    7. Налаштування middleware для визначення локалі

      Необов'язково

      Налаштуйте middleware для визначення переважної локалі користувача:

      src/middleware.ts
      export { intlayerMiddleware as middleware } from "next-intlayer/middleware";
      
      export const config = {
        matcher:
          "/((?!api|static|assets|robots|sitemap|sw|service-worker|manifest|.*\\..*|_next).*)",
      };
      intlayerMiddleware використовується для визначення переважної мови користувача та перенаправлення його на відповідний URL, як вказано в конфігурації. Крім того, він дозволяє зберігати перевагу мови користувача в cookie.
      Якщо вам потрібно зв'язати кілька middleware разом (наприклад, intlayerMiddleware з автентифікацією або кастомними middleware), Intlayer тепер надає хелпер під назвою multipleMiddlewares.
      ts
      import {  multipleMiddlewares,  intlayerMiddleware,} from "next-intlayer/middleware";import { customMiddleware } from "@utils/customMiddleware";export const middleware = multipleMiddlewares([  intlayerMiddleware,  customMiddleware,]);
    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({
            uk: "Створити додаток Next",
            en: "Create Next App",
            fr: "Créer une application Next.js",
            es: "Crear una aplicación Next.js",
          }),
          description: t({
            uk: "Згенеровано за допомогою create next app",
            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,
          },
        };
      };
      
      // ... Rest of the code
      Зверніть увагу, що функція 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>({
            uk: "Мій заголовок",
            en: "My title",
            fr: "Mon titre",
            es: "Mi título",
          }),
          description: t({
            uk: "Мій опис",
            en: "My description",
            fr: "Ma description",
            es: "Mi descripción",
          }),
        };
      };
      
      // ... Rest of the code
      Дізнайтеся більше про оптимізацію метаданих в офіційній документації Next.js.
    9. Інтернаціоналізація вашого sitemap.xml та robots.txt

      Необов'язково

      Щоб інтернаціоналізувати sitemap.xml та robots.txt, ви можете використати функцію getMultilingualUrls, надану Intlayer. Ця функція дозволяє генерувати багатомовні URL-адреси для вашого sitemap.

      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;
      Дізнайтеся більше про оптимізацію sitemap у офіційній документації Next.js. Дізнайтеся більше про оптимізацію robots.txt у офіційній документації Next.js.
    10. Зміна мови вашого контенту

      Необов'язково

      Щоб змінити мову вашого контенту в Next.js, рекомендується використовувати компонент Link для перенаправлення користувачів на відповідну локалізовану сторінку. Компонент Link дозволяє виконувати prefetch сторінки, що допомагає уникнути повного перезавантаження сторінки.

      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 // Забезпечить, що кнопка "назад" у браузері перенаправлятиме на попередню сторінку
                >
        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>
        );
      };
                  <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. Ця функція не дозволяє робити prefetch сторінки. Див. документацію по useLocale hook для детальнішої інформації.
      Ви також можете встановити функцію в опції onLocaleChange, щоб викликати користувацьку функцію при зміні локалі.
      src/components/LocaleSwitcher.tsx
      "use client";import { useRouter } from "next/navigation";import { useLocale } from "next-intlayer";import { getLocalizedUrl } from "intlayer";// ... Rest of the codeconst router = useRouter();const { setLocale } = useLocale({  onLocaleChange: (locale) => {    router.push(getLocalizedUrl(pathWithoutLocale, locale));  },});return (  <button onClick={() => setLocale(Locales.FRENCH)}>Change to French</button>);

      Посилання на документацію:

    11. Створення локалізованого компонента `Link`

      Необов'язково

      Щоб гарантувати, що навігація вашого додатку враховує поточну локаль, ви можете створити кастомний компонент Link. Цей компонент автоматично додає префікс внутрішнім URL відповідно до поточної мови. Наприклад, коли франкофонний користувач клікає на посилання на сторінку "About", він буде перенаправлений на /fr/about замість /about.

      Ця поведінка корисна з кількох причин:

      • SEO та User Experience: Локалізовані URL допомагають пошуковим системам правильно індексувати мовно-специфічні сторінки та надавати користувачам контент їхньою бажаною мовою.
      • Consistency: Використовуючи локалізоване посилання в усьому додатку, ви гарантуєте, що навігація залишатиметься в межах поточної локалі, запобігаючи несподіваним перемиканням мови.
      • Підтримуваність: Централізація логіки локалізації в одному компоненті спрощує керування URL-адресами, роблячи вашу codebase легшою для підтримки та розширення у міру зростання застосунку.

      Нижче наведено реалізацію локалізованого компонента 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 для автоматичного додавання префіксу з поточною локаллю. Це означає, що якщо ваш користувач використовує французьку, передання /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. Спочатку перевіряє заголовки запиту на наявність значення локалі, яке могло бути встановлене middleware
      2. Якщо локаль не знайдена в заголовках, вона шукає локаль у cookies
      3. Якщо cookie не знайдено, вона намагається визначити мову, переважну для користувача, за налаштуваннями браузера
      4. Як останній варіант, вона повертається до локалі за замовчуванням, налаштованої в застосунку

      Це забезпечує вибір найвідповіднішої локалі на основі наявного контексту.

    13. Оптимізуйте розмір bundle

      Необов'язково

      Під час використання next-intlayer словники за замовчуванням включаються в bundle для кожної сторінки. Щоб оптимізувати розмір bundle, Intlayer пропонує необов'язковий плагін для SWC, який за допомогою макросів інтелектуально замінює виклики useIntlayer. Це гарантує, що словники будуть включені в bundle лише для сторінок, які їх справді використовують.

      Щоб увімкнути цю оптимізацію, встановіть пакет @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, зміни в словниках за замовчуванням не будуть автоматично виявлятися.

    Це обмеження виникає тому, що Turbopack не може запускати webpack-плагіни паралельно для відстеження змін у ваших файлах контенту. Щоб обійти це, потрібно використовувати команду intlayer watch, яка дозволяє одночасно запускати сервер розробки та спостерігача збірки Intlayer.

    package.json
    {  // ... Ваші існуючі конфігурації package.json  "scripts": {    // ... Ваші існуючі налаштування скриптів    "dev": "intlayer watch --with 'next dev --turbopack'",  },}

    Налаштування 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.

    Встановити з Marketplace для VS Code

    Це розширення надає:

    • Автодоповнення для ключів перекладу.
    • Виявлення помилок у реальному часі для відсутніх перекладів.
    • Вбудований перегляд перекладеного контенту.
    • Швидкі дії для зручного створення та оновлення перекладів.

    Для детальнішої інформації про використання розширення зверніться до документації розширення Intlayer для VS Code.

    Далі

    Щоб розширити можливості, ви можете реалізувати візуальний редактор або винести свій контент, використовуючи CMS.