Creation:2025-12-07Last update:2026-05-31

    Перекладіть ваш вебсайт на React Router v7 (File-System Routes) за допомогою Intlayer | Інтернаціоналізація (i18n)

    Цей посібник демонструє, як інтегрувати Intlayer для безшовної інтернаціоналізації в проєктах на React Router v7 з використанням маршрутизації на основі файлової системи (@react-router/fs-routes) із маршрутизацією, що враховує локаль, підтримкою TypeScript та сучасними практиками розробки.

    Для клієнтської маршрутизації зверніться до посібника Intlayer з React Router v7.

    Зміст

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

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

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

    Замість того, щоб завантажувати великі файли 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 у додатку React Router v7 з файловою маршрутизацією

    www.youtube.com

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

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

      Встановіть необхідні пакети, використовуючи обраний менеджер пакетів:

      bash
      npm install intlayer react-intlayernpm install vite-intlayer --save-devnpm install @react-router/fs-routes --save-devnpx intlayer init
      • intlayer

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

      • react-intlayer Пакет, який інтегрує Intlayer у React-застосунок. Надає провайдери контексту та хуки для інтернаціоналізації в React.

      • vite-intlayer Включає плагін Vite для інтеграції Intlayer з Vite bundler, а також middleware для визначення бажаної локалі користувача, управління куками та обробки перенаправлень URL.

      • @react-router/fs-routes Пакет, який дозволяє маршрутизацію на основі файлової системи для React Router v7.

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

      Створіть файл конфігурації для налаштування мов вашого застосунку:

      intlayer.config.ts
      import { type IntlayerConfig, Locales } from "intlayer";
      
      const config: IntlayerConfig = {
        internationalization: {
          defaultLocale: Locales.ENGLISH,
          locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
        },
      };
      
      export default config;
      За допомогою цього файлу конфігурації ви можете налаштувати локалізовані URL-адреси, перенаправлення в middleware, назви cookie, розташування та розширення ваших декларацій контенту, вимкнути логи Intlayer у консолі та інше. Для повного списку доступних параметрів див. документацію з конфігурації.
    3. Інтегруйте Intlayer у вашу конфігурацію Vite

      Додайте плагін intlayer до вашої конфігурації:

      vite.config.ts
      import { reactRouter } from "@react-router/dev/vite";import { defineConfig } from "vite";import { intlayer } from "vite-intlayer";export default defineConfig({  plugins: [reactRouter(), intlayer()],});
      Плагін Vite intlayer() використовується для інтеграції Intlayer з Vite. Він забезпечує побудову файлів декларацій контенту та їх моніторинг у режимі розробки. Він визначає змінні середовища Intlayer у Vite-застосунку. Крім того, він додає аліаси для оптимізації продуктивності.
    4. Налаштування файлових маршрутів React Router v7

      Налаштуйте конфігурацію маршрутизації для використання файлової маршрутизації за допомогою flatRoutes:

      app/routes.ts
      import type { RouteConfig } from "@react-router/dev/routes";import { flatRoutes } from "@react-router/fs-routes";import { configuration } from "intlayer";const routes: RouteConfig = flatRoutes({  // Ігнорувати файли декларацій контенту, щоб їх не обробляли як маршрути  ignoredRouteFiles: configuration.content.fileExtensions.map(    (fileExtension) => `**/*${fileExtension}`  ),});export default routes;
      Функція flatRoutes з @react-router/fs-routes дозволяє використовувати маршрутизацію на основі файлової системи, де структура файлів у директорії routes/ визначає маршрути вашого застосунку. Опція ignoredRouteFiles гарантує, що файли декларації контенту Intlayer (наприклад, .content.ts тощо) не розглядатимуться як файли маршрутів.
    5. Створіть файли маршрутів за конвенціями файлової системи

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

      Створіть наступні файли у директорії app/routes/:

      Структура файлів

      bash
      app/├── root.tsx                         # Обгортка Layout для маршрутів локалі└──routes/    ├── ($locale)._index.tsx         # Головна сторінка (/, /es тощо)    ├── ($locale)._index.content.ts  # Вміст головної сторінки    ├── ($locale).about.tsx          # Сторінка About (/about, /es/about тощо)    └── ($locale).about.content.ts   # Вміст сторінки About

      The naming conventions:

      • ($locale) - Необов'язковий динамічний сегмент для параметра locale
      • _layout - Layout-маршрут, який обгортає дочірні маршрути
      • _index - Індексний маршрут (відображається на батьківському шляху)
      • . (dot) - Розділяє сегменти шляху (наприклад, ($locale).about/:locale?/about)

      Компонент Layout

      app/root.tsx
      import { getLocaleFromPath } from "intlayer";import { IntlayerProvider } from "react-intlayer";import {  isRouteErrorResponse,  Meta,  Outlet,  Scripts,  ScrollRestoration,  useLoaderData,} from "react-router";import type { Route } from "./+types/root";import "./app.css";// ... App, links та код ErrorBoundary без змінexport async function loader({ request }: Route.LoaderArgs) {  const locale = getLocaleFromPath(request.url);  return { locale };}export function Layout({  children,}: { children: React.ReactNode } & Route.ComponentProps) {  const data = useLoaderData<typeof loader>();  const { locale } = data ?? {};  return (    <html lang={locale}>      <head>        <meta charSet="utf-8" />        <meta content="width=device-width, initial-scale=1" name="viewport" />        <Meta />        <Links />      </head>      <body>        <IntlayerProvider locale={locale}>{children}</IntlayerProvider>        <ScrollRestoration />        <Scripts />      </body>    </html>  );}

      Головна сторінка

      app/routes/($locale)._index.tsx
      import { getIntlayer, validatePrefix } from "intlayer";import { useIntlayer } from "react-intlayer";import { data } from "react-router";import { LocaleSwitcher } from "~/components/locale-switcher";import { Navbar } from "~/components/navbar";import type { Route } from "./+types/($locale)._index";export const loader = ({ params }: Route.LoaderArgs) => {  const { locale } = params;  const { isValid } = validatePrefix(locale);  if (!isValid) {    throw data("Локаль не підтримується", { status: 404 });  }};export const meta: Route.MetaFunction = ({ params }) => {  const content = getIntlayer("page", params.locale);  return [    { title: content.title },    { content: content.description, name: "description" },  ];};export default function Page() {  const { title, description, aboutLink } = useIntlayer("page");  return (    <div>      <h1>{title}</h1>      <p>{description}</p>      <nav>        <LocalizedLink to="/about">{aboutLink}</LocalizedLink>      </nav>    </div>  );}

      Сторінка «Про нас»

      app/routes/($locale).about.tsx
      import { getIntlayer, validatePrefix } from "intlayer";import { useIntlayer } from "react-intlayer";import { data } from "react-router";import { LocaleSwitcher } from "~/components/locale-switcher";import { Navbar } from "~/components/navbar";import type { Route } from "./+types/($locale).about";export const loader = ({ params }: Route.LoaderArgs) => {  const { locale } = params;  const { isValid } = validatePrefix(locale);  if (!isValid) {    throw data("Локаль не підтримується", { status: 404 });  }};export const meta: Route.MetaFunction = ({ params }) => {  const content = getIntlayer("about", params.locale);  return [    { title: content.title },    { content: content.description, name: "description" },  ];};export default function AboutPage() {  const { title, content, homeLink } = useIntlayer("about");  return (    <div>      <h1>{title}</h1>      <p>{content}</p>      <nav>        <LocalizedLink to="/">{homeLink}</LocalizedLink>      </nav>    </div>  );}
      Якщо ваш застосунок уже існує, ви можете скористатися Intlayer Compiler у поєднанні з командой extract, щоб перетворити тисячі компонентів за одну секунду.
    6. Оголосіть свій контент

      Створюйте та керуйте деклараціями контенту для зберігання перекладів. Розміщуйте файли контенту поруч із файлами маршрутів:

      app/routes/($locale)._index.content.ts
      import { t, type Dictionary } from "intlayer";const pageContent = {  key: "page",  content: {    title: t({      uk: "Ласкаво просимо до React Router v7 + Intlayer",      en: "Welcome to React Router v7 + Intlayer",      es: "Bienvenido a React Router v7 + Intlayer",      fr: "Bienvenue sur React Router v7 + Intlayer",    }),    description: t({      uk: "Створюйте багатомовні додатки легко, використовуючи React Router v7 та Intlayer.",      en: "Build multilingual applications with ease using React Router v7 and Intlayer.",      es: "Cree aplicaciones multilingües fácilmente usando React Router v7 y Intlayer.",      uk: "Створюйте багатомовні додатки легко за допомогою React Router v7 та Intlayer.",      fr: "Créez des applications multilingues facilement avec React Router v7 et Intlayer.",    }),    aboutLink: t({      uk: "Дізнатися про нас",      en: "Learn About Us",      es: "Aprender Sobre Nosotros",      fr: "En savoir plus sur nous",    }),  },} satisfies Dictionary;export default pageContent;
      app/routes/($locale).about.content.ts
      import { t, type Dictionary } from "intlayer";const aboutContent = {  key: "about",  content: {    title: t({      uk: "Про нас",      en: "About Us",      es: "Sobre Nosotros",      fr: "À propos de nous",    }),    content: t({      uk: "Це вміст сторінки «Про нас».",      en: "This is the about page content.",      es: "Este es el contenido de la página de información.",      fr: "Ceci est le contenu de la page à propos.",    }),    homeLink: t({      uk: "Головна",      en: "Home",      es: "Inicio",      fr: "Accueil",    }),  },} satisfies Dictionary;export default aboutContent;
      Ваші декларації контенту можуть бути визначені будь-де у вашому застосунку, як тільки вони будуть включені до директорії contentDir (за замовчуванням ./app). І відповідати розширенню файлу декларації контенту (за замовчуванням .content.{json,ts,tsx,js,jsx,mjs,cjs,md,mdx,yaml,yml}).
      Для детальнішої інформації див. документацію щодо декларацій контенту.
    7. Створіть локалізовані компоненти

      Створіть компонент LocalizedLink для навігації з урахуванням локалі:

      app/components/localized-link.tsx
      import type { FC } from "react";import { getLocalizedUrl, type LocalesValues } from "intlayer";import { useLocale } from "react-intlayer";import { Link, type LinkProps, type To } from "react-router";const isExternalLink = (to: string) => /^(https?:)?\/\//.test(to);export const locacalizeTo = (to: To, locale: LocalesValues): To => {  if (typeof to === "string") {    if (isExternalLink(to)) {      return to;    }    return getLocalizedUrl(to, locale);  }  if (isExternalLink(to.pathname ?? "")) {    return to;  }  return {    ...to,    pathname: getLocalizedUrl(to.pathname ?? "", locale),  };};export const LocalizedLink: FC<LinkProps> = (props) => {  const { locale } = useLocale();  return <Link {...props} to={locacalizeTo(props.to, locale)} />;};

      У разі, якщо ви хочете переходити до локалізованих маршрутів, ви можете використати хук useLocalizedNavigate:

      app/hooks/useLocalizedNavigate.ts
      import { useLocale } from "react.intlayer";import { type NavigateOptions, type To, useNavigate } from "react-router";import { locacalizeTo } from "~/components/localized-link";export const useLocalizedNavigate = () => {  const navigate = useNavigate();  const { locale } = useLocale();  const localizedNavigate = (to: To, options?: NavigateOptions) => {    const localedTo = locacalizeTo(to, locale);    navigate(localedTo, options);  };  return localizedNavigate;};
    8. Створіть компонент перемикача локалі

      Створіть компонент, який дозволить користувачам змінювати мову:

      app/components/locale-switcher.tsx
      import type { FC } from "react";import {  getHTMLTextDir,  getLocaleName,  getLocalizedUrl,  getPathWithoutLocale,  Locales,} from "intlayer";import { useIntlayer, useLocale } from "react-intlayer";import { Link, useLocation } from "react-router";export const LocaleSwitcher: FC = () => {  const { localeSwitcherLabel } = useIntlayer("locale-switcher");  const { pathname } = useLocation();  const { availableLocales, locale } = useLocale();  const pathWithoutLocale = getPathWithoutLocale(pathname);  return (    <ol>      {availableLocales.map((localeItem) => (        <li key={localeItem}>          <Link            aria-current={localeItem === locale ? "page" : undefined}            aria-label={`${localeSwitcherLabel.value} ${getLocaleName(localeItem)}`}            reloadDocument // Перезавантажте сторінку, щоб застосувати нову локаль            to={getLocalizedUrl(pathWithoutLocale, 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>          </Link>        </li>      ))}    </ol>  );};
      Щоб дізнатися більше про хук useLocale, зверніться до документації.
    9. Додати керування атрибутами HTML

      Створіть хук для керування атрибутами lang та dir у HTML:

      app/hooks/useI18nHTMLAttributes.tsx
      import { getHTMLTextDir } from "intlayer";import { useEffect } from "react";import { useLocale } from "react-intlayer";export const useI18nHTMLAttributes = () => {  const { locale } = useLocale();  useEffect(() => {    document.documentElement.lang = locale;    document.documentElement.dir = getHTMLTextDir(locale);  }, [locale]);};

      Цей хук уже використовується в компоненті макета (($locale)._layout.tsx), показаному в кроці 5.

    10. Витягніть вміст ваших компонентів

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

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

      Щоб спростити цей процес, 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

    Configure TypeScript

    Intlayer uses module augmentation to get benefits of TypeScript and make your codebase stronger.

    Ensure your TypeScript configuration includes the autogenerated types:

    tsconfig.json
    {  // ... your existing configurations  include: [    // ... your existing includes    ".intlayer/**/*.ts", // Include the auto-generated types  ],}

    Git Configuration

    It is recommended to ignore the files generated by Intlayer. This allows you to avoid committing them to your Git repository.

    To do this, you can add the following instructions to your .gitignore file:

    .gitignore
    # Ignore the files generated by Intlayer.intlayer

    VS Code Extension

    To improve your development experience with Intlayer, you can install the official Intlayer VS Code Extension.

    Install from the VS Code Marketplace

    This extension provides:

    • Autocompletion for translation keys.
    • Real-time error detection for missing translations.
    • Inline previews of translated content.
    • Quick actions to easily create and update translations.

    For more details on how to use the extension, refer to the Intlayer VS Code Extension documentation.


    Go Further

    To go further, you can implement the visual editor or externalize your content using the CMS.


    Documentation References

    This comprehensive guide provides everything you need to integrate Intlayer with React Router v7 using file-system based routing for a fully internationalized application with locale-aware routing and TypeScript support.

    1. Додати middleware

      Ви також можете використовувати intlayerProxy для додавання server-side routing до вашого додатка. Цей плагін автоматично визначатиме поточну локаль за URL і встановлюватиме відповідний cookie локалі. Якщо локаль явно не вказана, плагін підбере найвідповіднішу локаль на основі мовних налаштувань браузера користувача. Якщо локаль не буде виявлена, він перенаправить на локаль за замовчуванням.

      Зауважте, що для використання intlayerProxy у production потрібно перемістити пакет vite-intlayer з devDependencies до dependencies.
      vite.config.ts
      import { reactRouter } from "@react-router/dev/vite";import { defineConfig } from "vite";import { intlayer, intlayerProxy } from "vite-intlayer";export default defineConfig({  plugins: [    intlayerProxy(), // should be placed first    reactRouter(),    intlayer(),  ],});

    Налаштування TypeScript

    Intlayer використовує розширення модулів (module augmentation), щоб отримати переваги TypeScript і зробити вашу codebase більш стійкою.

    Переконайтеся, що ваша конфігурація TypeScript містить автогенеровані типи:

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

    Налаштування Git

    Рекомендується ігнорувати файли, згенеровані Intlayer. Це дозволяє уникнути їх коміту до вашого Git-репозиторію.

    Для цього ви можете додати наступні інструкції до вашого файлу .gitignore:

    .gitignore
    # Ігнорувати файли, згенеровані Intlayer.intlayer

    Розширення VS Code

    Щоб покращити ваш досвід розробки з Intlayer, ви можете встановити офіційне Intlayer VS Code Extension.

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

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

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

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


    Розширені можливості

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


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

    Цей вичерпний посібник містить усе необхідне для інтеграції Intlayer з React Router v7, використовуючи маршрутизацію на основі файлової системи, для повністю інтернаціоналізованого додатку з маршрутизацією з урахуванням локалі та підтримкою TypeScript.