Автор:
    Создание:2025-08-23Последнее обновление:2026-08-30

    Переведите ваш Create React App с Intlayer | Интернационализация (i18n)

    ide.intlayer.org

    Смотрите Application Template на GitHub.

    Что такое Intlayer?

    По сравнению с основными решениями, такими как react-i18next или i18next, Intlayer — это решение, которое поставляется со встроенными оптимизациями, такими как:

    Intlayer - это инновационная, открытая библиотека интернационализации (i18n), созданная для упрощения поддержки многоязычности в современных веб-приложениях.

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

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

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

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

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

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

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


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

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

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

      bash
      npx intlayer init --interactive
      
      флаг --interactive не является обязательным. Используйте intlayer-cli init, если вы являетесь ИИ-агентом.
      Эта команда определит вашу среду и установит необходимые пакеты. Например:
      bash
      npm install intlayer react-intlayer react-scripts-intlayer
      
      • intlayer

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

      • react-intlayer

        Пакет, интегрирующий Intlayer с React-приложением. Он предоставляет провайдеры контекста и хуки для интернационализации в React.

      • react-scripts-intlayer

      Включает команды и плагины react-scripts-intlayer для интеграции Intlayer с приложением на основе Create React App. Эти плагины основаны на craco и включают дополнительную конфигурацию для сборщика Webpack.

    2. Конфигурация вашего проекта

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

      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 в конфигурацию CRA

      Измените ваши скрипты для использования react-intlayer

      package.json
        "scripts": {
          "build": "react-scripts-intlayer build",
          "start": "react-scripts-intlayer start",
          "transpile": "intlayer build"
        },
      
      Скрипты react-scripts-intlayer основаны на CRACO. Вы также можете реализовать собственную настройку на основе плагина intlayer для craco. См. пример здесь.
    4. Декларация вашего контента

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

      src/app.content.tsx
      import { t, type Dictionary } from "intlayer";
      import React, { type ReactNode } from "react";
      
      const appContent = {
        key: "app",
        content: {
          getStarted: t<ReactNode>({
            ru: (
              <>
                Редактируйте <code>src/App.tsx</code> и сохраните для перезагрузки
              </>
            ),
            en: (
              <>
                Edit <code>src/App.tsx</code> and save to reload
              </>
            ),
            fr: (
              <>
                Éditez <code>src/App.tsx</code> et enregistrez pour recharger
              </>
            ),
            es: (
              <>
                Edita <code>src/App.tsx</code> y guarda para recargar
              </>
            ),
          }),
          reactLink: {
            href: "https://reactjs.org",
            content: t({
              ru: "Изучить React",
              en: "Learn React",
              fr: "Apprendre React",
              es: "Aprender React",
            }),
          },
        },
      } satisfies Dictionary;
      
      export default appContent;
      
      Ваши декларации контента могут быть определены в любом месте вашего приложения, если они включены в каталог contentDir (по умолчанию, ./src) и соответствуют расширению файла декларации контента (по умолчанию, .content.{json,ts,tsx,js,jsx,mjs,cjs,md,mdx,yaml,yml}).
      Для получения более подробной информации обратитесь к документации по декларации контента.
      Если ваш файл контента включает код TSX, вам следует импортировать import React from "react"; в ваш файл контента.
    5. Использование Intlayer в вашем коде

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

      src/App.tsx
      import logo from "./logo.svg";
      import "./App.css";
      import type { FC } from "react";
      import { IntlayerProvider, useIntlayer } from "react-intlayer";
      
      const AppContent: FC = () => {
        const content = useIntlayer("app");
      
        return (
          <div className="App">
            <img src={logo} className="App-logo" alt="logo" />
      
            {content.getStarted}
            <a
              className="App-link"
              href={content.reactLink.href.value}
              target="_blank"
              rel="noopener noreferrer"
            >
              {content.reactLink.content}
            </a>
          </div>
        );
      };
      
      const App: FC = () => (
        <IntlayerProvider>
          <AppContent />
        </IntlayerProvider>
      );
      
      export default App;
      
      Примечание: если вы хотите использовать ваш контент в атрибуте 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, обратитесь к документации.

      Чтобы узнать больше о хуке useIntlayer, обратитесь к документации.
    6. Изменение языка вашего контента

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

      Чтобы изменить язык вашего контента, вы можете использовать функцию setLocale, предоставляемую хуком useLocale. Эта функция позволяет установить локаль приложения и обновить контент соответствующим образом.

      src/components/LocaleSwitcher.tsx
      import { Locales } from "intlayer";
      import { useLocale } from "react-intlayer";
      
      const LocaleSwitcher = () => {
        const { setLocale } = useLocale();
      
        return (
          <button onClick={() => setLocale(Locales.English)}>
            Change Language to English
          </button>
        );
      };
      
      Чтобы узнать больше о хуке useLocale, обратитесь к документации.
    7. Добавьте локализованную маршрутизацию в ваше приложение

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

      Цель этого шага - создать уникальные маршруты для каждого языка. Это полезно для SEO и удобных для SEO URL. Пример:

      plaintext
      - https://example.com/about
      - https://example.com/es/about
      - https://example.com/fr/about
      
      По умолчанию маршруты не имеют префикса для локали по умолчанию. Если вы хотите добавить префикс для локали по умолчанию, вы можете установить опцию middleware.prefixDefault в значение true в вашей конфигурации. Подробнее см. в документации по конфигурации.

      Чтобы добавить локализованную маршрутизацию в ваше приложение, вы можете создать компонент LocaleRouter, который обернет маршруты вашего приложения и будет обрабатывать маршрутизацию на основе локали. Вот пример с использованием React Router:

      src/components/LocaleRouter.tsx
      // Importing necessary dependencies and functions
      import { type Locales, configuration, getPathWithoutLocale } from "intlayer"; // Утилиты и типы из 'intlayer'
      // Утилиты и типы из 'intlayer'
      import type { FC, PropsWithChildren } from "react"; // Типы React для функциональных компонентов и пропсов
      import { IntlayerProvider } from "react-intlayer"; // Провайдер для контекста интернационализации
      import {
        BrowserRouter,
        Routes,
        Route,
        Navigate,
        useLocation,
      } from "react-router-dom"; // Компоненты роутера для управления навигацией
      
      // Деструктуризация конфигурации из Intlayer
      const { internationalization, middleware } = configuration;
      const { locales, defaultLocale } = internationalization;
      
      /**
       * Компонент, который обрабатывает локализацию и оборачивает дочерние элементы в соответствующий контекст локали.
       * Он управляет определением и проверкой локали на основе URL.
       */
      const AppLocalized: FC<PropsWithChildren<{ locale: Locales }>> = ({
        children,
        locale,
      }) => {
        const { pathname, search } = useLocation(); // Получить текущий путь URL
      
        // Определить текущую локаль, используя локаль по умолчанию, если не указана
        const currentLocale = locale ?? defaultLocale;
      
        // Удалить префикс локали из пути для построения базового пути
        const pathWithoutLocale = getPathWithoutLocale(
          pathname // Текущий путь URL
        );
      
        /**
         * Если middleware.prefixDefault равно true, локаль по умолчанию всегда должна иметь префикс.
         */
        if (middleware.prefixDefault) {
          // Проверить локаль
          if (!locale || !locales.includes(locale)) {
            // Перенаправить на локаль по умолчанию с обновлённым путём
            return (
              <Navigate
                to={`/${defaultLocale}/${pathWithoutLocale}${search}`}
                replace // Замена текущей записи в истории на новую
              />
            );
          }
      
          // Обернуть дочерние элементы в IntlayerProvider и установить текущую локаль
          return (
            <IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
          );
        } else {
          /**
           * Когда middleware.prefixDefault равно false, локаль по умолчанию не имеет префикса.
           * Убедитесь, что текущая локаль действительна и не является локалью по умолчанию.
           */
          if (
            currentLocale.toString() !== defaultLocale.toString() &&
            !locales
              .filter(
                (locale) => locale.toString() !== defaultLocale.toString() // Исключить локаль по умолчанию
              )
              .includes(currentLocale) // Проверка, находится ли текущая локаль в списке допустимых локалей
          ) {
            // Перенаправление на путь без префикса локали
            return <Navigate to={`${pathWithoutLocale}${search}`} replace />;
          }
      
          // Оборачивание дочерних элементов с использованием IntlayerProvider и установки текущей локали
          return (
            <IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
          );
        }
      };
      
      /**
       * Компонент маршрутизатора, который настраивает маршруты для конкретных локалей.
       * Использует React Router для управления навигацией и рендеринга локализованных компонентов.
       */
      export const LocaleRouter: FC<PropsWithChildren> = ({ children }) => (
        <BrowserRouter>
          <Routes>
            {locales
              .filter(
                (locale) => middleware.prefixDefault || locale !== defaultLocale
              )
              .map((locale) => (
                <Route
                  // Шаблон маршрута для захвата локали (например, /en/, /fr/) и всех последующих путей
                  path={`/${locale}/*`}
                  key={locale}
                  element={<AppLocalized locale={locale}>{children}</AppLocalized>} // Оборачивает дочерние элементы с управлением локалью
                />
              ))}
      
            {
              // Если префикс для локали по умолчанию отключен, рендерить дочерние элементы напрямую по корневому пути
              !middleware.prefixDefault && (
                <Route
                  path="*"
                  element={
                    <AppLocalized locale={defaultLocale}>{children}</AppLocalized>
                  } // Оборачивает дочерние элементы с управлением локалью
                />
              )
            }
          </Routes>
        </BrowserRouter>
      );
      

      Затем вы можете использовать компонент LocaleRouter в вашем приложении:

      src/App.tsx
      import { LocaleRouter } from "./components/LocaleRouter";
      import type { FC } from "react";
      
      // ... Ваш компонент AppContent
      
      const App: FC = () => (
        <LocaleRouter>
          <AppContent />
        </LocaleRouter>
      );
      
    8. Изменение URL при смене локали

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

      Чтобы изменить URL при смене локали, вы можете использовать проп onLocaleChange, предоставляемый хуком useLocale. Параллельно можно использовать хуки useLocation и useNavigate из react-router-dom для обновления пути URL.

      src/components/LocaleSwitcher.tsx
      import { useLocation, useNavigate } from "react-router-dom";
      import {
        Locales,
        getHTMLTextDir,
        getLocaleName,
        getLocalizedUrl,
      } from "intlayer";
      import { useLocale } from "react-intlayer";
      import { type FC } from "react";
      
      const LocaleSwitcher: FC = () => {
        const { pathname, search } = useLocation(); // Получаем текущий путь URL. Пример: /fr/about?foo=bar
        const navigate = useNavigate();
      
        const { locale, availableLocales, setLocale } = useLocale({
          onLocaleChange: (locale) => {
            // Построить URL с обновленной локалью
            // Пример: /es/about?foo=bar
            const pathWithLocale = getLocalizedUrl(`${pathname}${search}`, locale);
      
            // Обновить путь URL
            navigate(pathWithLocale);
          },
        });
      
        return (
          <div>
            <button popoverTarget="localePopover">{getLocaleName(locale)}</button>
            <div id="localePopover" popover="auto">
              {availableLocales.map((localeItem) => (
                <a
                  href={getLocalizedUrl(location.pathname, localeItem)}
                  hrefLang={localeItem}
                  aria-current={locale === localeItem ? "page" : undefined}
                  onClick={(e) => {
                    e.preventDefault();
                    setLocale(localeItem);
                  }}
                  key={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>
                </a>
              ))}
            </div>
          </div>
        );
      };
      

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

    9. Переключение атрибутов языка и направления в HTML

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

      Когда ваше приложение поддерживает несколько языков, крайне важно обновлять атрибуты lang и dir тега <html>, чтобы они соответствовали текущей локали. Это обеспечивает:

      • Доступность: программы чтения с экрана и вспомогательные технологии полагаются на правильный атрибут lang для точного произношения и интерпретации содержимого.
      • Отображение текста: атрибут dir (направление) обеспечивает правильный порядок отображения текста (например, слева направо для английского, справа налево для арабского или иврита), что важно для удобочитаемости.
      • SEO: поисковые системы используют атрибут lang для определения языка вашей страницы, помогая показывать правильный локализованный контент в результатах поиска.

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

      Реализация хука

      Создайте пользовательский хук для управления атрибутами HTML. Хук отслеживает изменения локали и обновляет атрибуты соответствующим образом:

      src/hooks/useI18nHTMLAttributes.tsx
      import { useEffect } from "react";
      import { useLocale } from "react-intlayer";
      import { getHTMLTextDir } from "intlayer";
      
      /**
       * Обновляет атрибуты `lang` и `dir` элемента <html> в зависимости от текущей локали.
       * - `lang`: Информирует браузеры и поисковые системы о языке страницы.
       * - `dir`: Обеспечивает правильный порядок чтения (например, 'ltr' для английского, 'rtl' для арабского).
       *
       * Это динамическое обновление необходимо для корректного отображения текста, доступности и SEO.
       */
      export const useI18nHTMLAttributes = () => {
        const { locale } = useLocale();
      
        useEffect(() => {
          // Обновляет атрибут языка на текущую локаль.
          document.documentElement.lang = locale;
      
          // Устанавливает направление текста в зависимости от текущей локали.
          document.documentElement.dir = getHTMLTextDir(locale);
        }, [locale]);
      };
      

      Использование хука в вашем приложении

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

      src/App.tsx
      import type { FC } from "react";
      import { IntlayerProvider, useIntlayer } from "react-intlayer";
      import { useI18nHTMLAttributes } from "./hooks/useI18nHTMLAttributes";
      import "./App.css";
      
      const AppContent: FC = () => {
        // Примените хук для обновления атрибутов lang и dir тега <html> на основе локали.
        useI18nHTMLAttributes();
      
        // ... Остальная часть вашего компонента
      };
      
      const App: FC = () => (
        <IntlayerProvider>
          <AppContent />
        </IntlayerProvider>
      );
      
      export default App;
      

      Применяя эти изменения, ваше приложение будет:

      • Обеспечивать корректное отражение текущей локали в атрибуте языка (lang), что важно для SEO и поведения браузера.
      • Настраивать направление текста (dir) в соответствии с локалью, улучшая читаемость и удобство использования для языков с разным порядком чтения.
      • Обеспечивать более доступный опыт, поскольку вспомогательные технологии зависят от этих атрибутов для оптимальной работы.

    Настройка TypeScript

    Intlayer использует расширение модулей (module augmentation), чтобы получить преимущества TypeScript и сделать вашу кодовую базу более надежной.

    Autocompletion

    Translation error

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

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

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

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

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

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

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

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

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

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

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

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

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

    Для расширения возможностей вы можете реализовать визуальный редактор или вынести ваш контент во внешний CMS.

    Часто задаваемые вопросы

    • react-i18next / i18next: самый распространённый, с пространствами имён JSON, загружаемыми во время выполнения.
    • react-intl и Lingui: формат сообщений ICU, на основе извлечения.
    • Intlayer: контент, объявленный рядом с каждым компонентом и скомпилированный во время сборки через react-scripts-intlayer, полностью типизированный, с ИИ-переводом, визуальным редактором и CMS.

    Create React App оборачивает собственную конфигурацию webpack, поэтому интеграция идёт через react-scripts-intlayer - замену react-scripts, а не через плагин, который вы регистрируете сами. См. почему Intlayer и бенчмарк.

    Гораздо меньше, чем при подходе на основе пространств имён, потому что страница никогда не загружает каталог, который не отображает. Компилятор во время сборки заменяет вызовы useIntlayer точными записями словаря, которые использует компонент, поэтому неиспользуемые ключи и неиспользуемые языки отбрасываются, а динамические словари разделяют остальное по локалям. По сравнению с обычными альтернативами Intlayer сокращает размер бандла и страницы до 50%. См. оптимизацию бандла и бенчмарк.

    Да, и есть два пути. Вы можете мигрировать контент постепенно с помощью руководства по миграции с react-i18next или руководства по миграции с i18next. Или вы можете полностью сохранить свой текущий API: адаптеры совместимости предоставляют точно такой же API, как react-i18next, react-intl и i18next, но обслуживаемый словарями Intlayer, поэтому меняются импорты, а код компонентов - нет.

    Да. Плагин синхронизации JSON сохраняет ваши файлы /messages/{locale}/{namespace}.json как источник истины и генерирует из них словари Intlayer, в обоих направлениях. Плагин синхронизации PO делает то же самое для каталогов gettext, а файлы по локали позволяют разделить контент по языкам вместо группировки локалей в одном файле.

    Нет. Запустите npx intlayer extract, и Intlayer прочитает ваши компоненты, извлечёт строки, видимые пользователю, и запишет файл .content рядом с каждым из них, так что вы просматриваете diff вместо копирования строк в каталог по одной.

    Для полностью автоматизированного конвейера Компилятор Intlayer делает то же самое во время сборки: он сканирует исходный код JSX, TSX, Vue и Svelte при каждом изменении, генерирует словари и поддерживает их синхронизацию через горячую замену модулей, поэтому вручную поддерживать ключи вообще не нужно.

    Стоит знать о двух ограничениях, прежде чем включать компилятор. Он работает через статический анализ, поэтому строки, существующие только во время выполнения, такие как коды ошибок API или поля CMS, остаются недоступными. И ему нужно отличать текст, видимый пользователю, от логики приложения вроде className="active" или кода статуса, что требует нескольких аннотаций в большой кодовой базе. Команда extract избегает обоих ограничений, оставляя вас в процессе.

    Пять компонентов, все опциональные:

    • Расширение для VS Code: переход от ключа useIntlayer к файлу контента, который его объявляет, извлечение контента из компонента и запуск build, fill, test, push и pull из палитры команд или отдельной вкладки Intlayer.
    • LSP-сервер: та же осведомлённость в любом редакторе, который говорит на LSP, с переходом к определению, поиском всех ссылок, предпросмотром переведённого значения при наведении, автодополнением ключей и полей и предупреждением, когда ключ нигде не объявлен. Он также разрешает вызовы i18next, react-i18next, next-intl и use-intl, что помогает при миграции.
    • MCP-сервер: предоставляет документацию и CLI Intlayer для Cursor, VS Code, Claude Desktop, Claude Code и ChatGPT, чтобы ассистент отвечал по актуальной документации, а не гадал, и мог сам запускать команды вроде intlayer fill.
    • Навыки агентов: сфокусированные навыки, такие как intlayer-config, intlayer-cli и intlayer-content, плюс по одному на фреймворк, которые обучают агента вашей настройке маршрутизации и типам узлов контента.
    • Плагин ESLint: no-raw-text помечает жёстко закодированные строки, с дополнительными правилами для статических ключей словаря и неиспользуемого контента.