ГоловнаПісочницяВітринаДодатокДокументаціяБлог
    • 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. Vite та React
    4. React Router v7 (fs-routes)
    Дата створення:2025-12-07Останнє оновлення:2026-05-06
    Переглянути шаблон додатку на GitHub

    На цій сторінці доступний шаблон додатку.

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

    Ця сторінка веде на живу демонстрацію шаблону.

    Переглянути відеоурок

    На цій сторінці доступний відеоурок.

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

    Задайте питання та отримайте підсумок документа, вказавши цю сторінку та обраного вами постачальника штучного інтелекту

    Історія версій

    1. "Оновлення використання API useIntlayer у Solid для прямого доступу до властивостей"
      v8.9.004.05.2026
    2. "Додано команду init"
      v7.5.930.12.2025
    3. "Оновлено Layout та додано обробку 404"
      v7.5.627.12.2025
    4. "Ініціалізовано history"
      v7.3.408.12.2025

    Вміст цієї сторінки перекладено за допомогою штучного інтелекту.

    Переглянути останню версію оригінального вмісту англійською
    Редагувати цей документ

    Якщо у вас є ідея щодо покращення цієї документації, будь ласка, долучіться, надіславши pull request на GitHub.

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

    Скопіювати документацію у форматі Markdown в буфер обміну

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

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

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

    Зміст

    Що таке Intlayer?

    Intlayer, інноваційна, open-source бібліотека інтернаціоналізації (i18n), створена для спрощення підтримки кількох мов у сучасних вебдодатках.

    З Intlayer ви можете:

    • Легко керувати перекладами за допомогою декларативних словників на рівні компонентів.
    • Динамічно локалізувати метадані, маршрути та контент.
    • Забезпечити підтримку TypeScript за допомогою автогенерованих типів, що покращує автодоповнення та виявлення помилок.
    • Використовувати розширені можливості, такі як динамічне визначення локалі та її переключення.
    • Увімкнути маршрутизацію з урахуванням локалі за допомогою файлово-системної маршрутизації React Router v7.

    Покроковий посібник із налаштування Intlayer у додатку React Router v7 з файловою маршрутизацією

    www.youtube.com
    ide.intlayer.org
    intlayer-react-router-v7-fs-routes.vercel.app

    Дивіться 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}).
    Для детальнішої інформації див. документацію щодо декларацій контенту.

    Крок 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.

    (Необов'язково) Крок 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

    Оновіть свій vite.config.ts, щоб включити плагін intlayerCompiler:

    vite.config.ts
    Копіювати код

    Скопіюйте код у буфер обміну

    import { defineConfig } from "vite";import { intlayer, intlayerCompiler } from "vite-intlayer";export default defineConfig({ plugins: [   intlayer(),   intlayerCompiler(), // Додає плагін компілятора ],});
    bash
    Копіювати код

    Скопіюйте код у буфер обміну

    npm run build # Або npm run dev

    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

    • Intlayer Documentation
    • React Router v7 Documentation
    • React Router fs-routes Documentation
    • useIntlayer hook
    • useLocale hook
    • Content Declaration
    • Configuration

    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.

    Крок 10: Додати 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
    • Документація React Router fs-routes
    • Хук useIntlayer
    • Хук useLocale
    • Оголошення контенту
    • Конфігурація

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

    React Router v7
    Compiler
    Alt+→

    На цій сторінці

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

      npm install intlayer react-intlayernpm install vite-intlayer --save-devnpm install @react-router/fs-routes --save-devnpx intlayer init
      import { reactRouter } from "@react-router/dev/vite";import { defineConfig } from "vite";import { intlayer } from "vite-intlayer";export default defineConfig({  plugins: [reactRouter(), intlayer()],});
      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;
      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
      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>  );}
      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>  );}
      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>  );}
      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;
      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;
      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)} />;};
      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;};
      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>  );};
      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]);};
      npx intlayer extract
      import { defineConfig } from "vite";import { intlayer, intlayerCompiler } from "vite-intlayer";export default defineConfig({ plugins: [   intlayer(),   intlayerCompiler(), // Додає плагін компілятора ],});
      npm run build # Або npm run dev
      {  // ... your existing configurations  include: [    // ... your existing includes    ".intlayer/**/*.ts", // Include the auto-generated types  ],}
      # Ignore the files generated by Intlayer.intlayer
      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(),  ],});
      {  // ... ваші існуючі конфігурації  include: [    // ... ваші існуючі include    ".intlayer/**/*.ts", // Включити автогенеровані типи  ],}
      # Ігнорувати файли, згенеровані Intlayer.intlayer