ГлавнаяПесочницаВитринаПриложениеДокументБлог
    • 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 and vanilla
    Создание:2026-03-23Последнее обновление:2026-05-06
    Посмотреть шаблон приложения на GitHub

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

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

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

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

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

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

    1. "Обновление использования API useIntlayer в Solid для прямого доступа к свойствам"
      v8.9.004.05.2026
    2. "Начальная история"
      v8.4.1023.03.2026

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

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

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

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

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

    Переведите ваш сайт на Vite и Vanilla JS с помощью Intlayer | Интернационализация (i18n)

    ide.intlayer.org
    intlayer-vite-vanilla.vercel.app

    Содержание

    Что такое Intlayer?

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

    С Intlayer вы можете:

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

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

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

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

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

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

    npm install intlayer vanilla-intlayernpm install vite-intlayer --save-devnpx intlayer init
    • intlayer Основной пакет, предоставляющий инструменты интернационализации для управления конфигурацией, перевода, объявления контента, транспиляции и команд CLI.

    • vanilla-intlayer Пакет для интеграции Intlayer в приложения на чистом JavaScript / TypeScript. Он предоставляет синглтон pub/sub (IntlayerClient) и вспомогательные функции на основе колбэков (useIntlayer, useLocale и т. д.), чтобы любая часть вашего приложения могла реагировать на изменения языка без зависимости от UI-фреймворка.

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

    Шаг 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, перенаправление посредника, имена куки, местоположение и расширение ваших объявлений контента, отключить логи Intlayer в консоли и многое другое. Полный список доступных параметров см. в документации по конфигурации.

    Шаг 3: Интеграция Intlayer в конфигурацию Vite

    Добавьте плагин intlayer в вашу конфигурацию.

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

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

    import { defineConfig } from "vite";
    import { intlayer } from "vite-intlayer";
    
    // https://vitejs.dev/config/
    export default defineConfig({
      plugins: [intlayer()],
    });
    Плагин Vite intlayer() используется для интеграции Intlayer с Vite. Он обеспечивает сборку файлов объявления контента и отслеживает их изменения в режиме разработки. Он определяет переменные окружения Intlayer внутри приложения Vite. Кроме того, он предоставляет псевдонимы (aliases) для оптимизации производительности.

    Шаг 4: Инициализация Intlayer в точке входа

    Вызовите installIntlayer() перед рендерингом любого контента, чтобы глобальный синглтон языка был готов.

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

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

    import { installIntlayer } from "vanilla-intlayer";// Должно быть вызвано перед рендерингом любого i18n контента.installIntlayer();// Импортируйте и запустите модули вашего приложения.import "./app.js";

    Если вы также используете объявления контента md() (Markdown), установите также рендерер макрдауна:

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

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

    import { installIntlayer, installIntlayerMarkdown } from "vanilla-intlayer";installIntlayer();installIntlayerMarkdown();import "./app.js";

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

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

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

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

    import { insert, t, type Dictionary } from "intlayer";
    
    const appContent = {
      key: "app",
      content: {
        title: "Vite + Vanilla",
    
        viteLogoLabel: t({
          en: "Vite Logo",
          fr: "Logo Vite",
          es: "Logo Vite",
        }),
    
        count: insert(
          t({
            en: "count is {{count}}",
            fr: "le compte est {{count}}",
            es: "el recuento es {{count}}",
          })
        ),
    
        readTheDocs: t({
          en: "Click on the Vite logo to learn more",
          fr: "Cliquez sur le logo Vite pour en savoir plus",
          es: "Нажмите на логотип Vite, чтобы узнать больше",
        }),
      },
    } satisfies Dictionary;
    
    export default appContent;

    Ваши объявления контента могут быть определены в любом месте вашего приложения, при условии, что они включены в каталог contentDir (по умолчанию ./src) и соответствуют расширению файла объявления контента (по умолчанию .content.{json,ts,tsx,js,jsx,mjs,cjs}).

    Дополнительную информацию см. в документации по объявлению контента.

    Шаг 6: Использование Intlayer в вашем JavaScript

    vanilla-intlayer повторяет поверхностный API react-intlayer: useIntlayer(key, locale?) возвращает переведенный контент напрямую. Добавьте .onChange() к результату, чтобы подписаться на изменения языка - это явный эквивалент ререндеринга в React.

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

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

    import { installIntlayer, useIntlayer } from "vanilla-intlayer";installIntlayer();// Получите начальный контент для текущего языка.// Добавьте .onChange(), чтобы получать уведомления при смене языка.const content = useIntlayer("app").onChange((newContent) => {  // Перерисуйте или обновите только затронутые узлы DOM  document.querySelector<HTMLHeadingElement>("h1")!.textContent = String(    newContent.title  );  document.querySelector<HTMLParagraphElement>(".read-the-docs")!.textContent =    String(newContent.readTheDocs);});// Начальный рендерингdocument.querySelector<HTMLHeadingElement>("h1")!.textContent = String(  content.title);document.querySelector<HTMLParagraphElement>(".read-the-docs")!.textContent =  String(content.readTheDocs);

    Обращайтесь к значениям как к строкам, оборачивая их в String(), что вызывает метод toString() узла и возвращает переведенный текст.

    Когда вам нужно значение для стандартного HTML-атрибута (например, alt, aria-label), используйте .value напрямую:

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

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

    img.alt = content.viteLogoLabel.value;

    (Опционально) Шаг 7: Изменение языка вашего контента

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

    src/locale-switcher.ts
    Копировать код

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

    import { getLocaleName } from "intlayer";import { useLocale } from "vanilla-intlayer";export function setupLocaleSwitcher(container: HTMLElement): () => void {  const { locale, availableLocales, setLocale, subscribe } = useLocale();  const select = document.createElement("select");  select.setAttribute("aria-label", "Language");  const render = (currentLocale: string) => {    select.innerHTML = availableLocales      .map(        (loc) =>          `<option value="${loc}"${loc === currentLocale ? " selected" : ""}>            ${getLocaleName(loc)}          </option>`      )      .join("");  };  render(locale);  container.appendChild(select);  select.addEventListener("change", () => setLocale(select.value as any));  // Синхронизация выпадающего списка при изменении языка из другого места  return subscribe((newLocale) => render(newLocale));}

    (Опционально) Шаг 8: Рендеринг контента Markdown и HTML

    Intlayer поддерживает объявления контента md() и html(). В чистом JS скомпилированный результат вставляется как необработанный HTML через innerHTML.

    Компиляция и вставка HTML:

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

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

    import {  compileMarkdown,  installIntlayerMarkdown,  useIntlayer,} from "vanilla-intlayer";installIntlayerMarkdown();const content = useIntlayer("app").onChange((newContent) => {  const el = document.querySelector<HTMLDivElement>(".edit-note")!;  el.innerHTML = compileMarkdown(String(newContent.editNote));});document.querySelector<HTMLDivElement>(".edit-note")!.innerHTML =  compileMarkdown(String(content.editNote));
    TIP
    String(content.editNote) вызывает toString() для IntlayerNode, который возвращает необработанную строку Markdown. Передайте её в compileMarkdown, чтобы получить HTML-строку, а затем установите через innerHTML.
    WARNING

    Используйте innerHTML только для доверенного контента. Если макрдаун получен из пользовательского ввода, сначала очистите его (например, с помощью DOMPurify). Вы можете динамически установить рендерер с очисткой:

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

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

    import { installIntlayerMarkdownDynamic } from "vanilla-intlayer";await installIntlayerMarkdownDynamic(async () => {  const DOMPurify = await import("dompurify");  return (markdown) => DOMPurify.sanitize(compileMarkdown(markdown));});

    (Опционально) Шаг 9: Добавление локализованной маршрутизации в ваше приложение

    Чтобы создать уникальные маршруты для каждого языка (полезно для SEO), вы можете использовать intlayerProxy в вашей конфигурации Vite для определения языка на стороне сервера.

    Сначала добавьте intlayerProxy в конфигурацию Vite:

    Обратите внимание, что для использования intlayerProxy в продакшене вам нужно переместить vite-intlayer из devDependencies в dependencies.
    vite.config.ts
    Копировать код

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

    import { defineConfig } from "vite";
    import { intlayer, intlayerProxy } from "vite-intlayer";
    
    export default defineConfig({
      plugins: [
        intlayerProxy(), // должен быть первым
        intlayer(),
      ],
    });

    (Опционально) Шаг 10: Изменение URL при смене языка

    Чтобы обновлять URL браузера при смене языка, вызовите useRewriteURL() после установки Intlayer:

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

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

    import { installIntlayer, useRewriteURL } from "vanilla-intlayer";installIntlayer();// Перезаписывает URL немедленно и при каждой последующей смене языка.// Возвращает функцию отписки для очистки.const stopRewriteURL = useRewriteURL();

    (Опционально) Шаг 11: Переключение атрибутов языка и направления текста HTML

    Обновляйте атрибуты lang и dir тега <html> в соответствии с текущим языком для обеспечения доступности и SEO.

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

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

    import { getHTMLTextDir } from "intlayer";import { installIntlayer, useLocale } from "vanilla-intlayer";installIntlayer();useLocale({  onLocaleChange: (locale) => {    document.documentElement.lang = locale;    document.documentElement.dir = getHTMLTextDir(locale);  },});

    (Опционально) Шаг 12: Ленивая загрузка словарей по языкам

    Для больших приложений вы можете разделить словари по языкам на отдельные чанки. Используйте useDictionaryDynamic вместе с динамическим import() от Vite:

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

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

    import { installIntlayer, useDictionaryDynamic } from "vanilla-intlayer";installIntlayer();const unsubscribe = useDictionaryDynamic(  {    en: () => import("../.intlayer/dictionaries/en/app.mjs"),    fr: () => import("../.intlayer/dictionaries/fr/app.mjs"),    es: () => import("../.intlayer/dictionaries/es/app.mjs"),  },  "app").onChange((content) => {  document.querySelector("h1")!.textContent = String(content.title);});
    Бандл каждого языка запрашивается только тогда, когда этот язык становится активным, и результат кэшируется - последующие переключения на тот же язык происходят мгновенно.

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

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

    Чтобы облегчить этот процесс, 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

    (Опционально) Sitemap и robots.txt (генерация на сборке)

    Intlayer предоставляет generateSitemap и getMultilingualUrls - утилиты, которые формируют многоязычные sitemap.xml и robots.txt для краулеров и позволяют автоматически записать их в public/. Обычно запускают небольшой Node-скрипт до Vite (например, npm-хуки predev / prebuild).

    Sitemap

    Генератор sitemap учитывает локали и добавляет нужные метаданные.

    Поддерживается пространство имён xhtml:link (hreflang). Вместо плоского списка URL Intlayer связывает все языковые версии страницы в обе стороны (например /about, /fr/about или /about?lang=fr в зависимости от режима маршрутизации).

    Robots.txt

    Используйте getMultilingualUrls, чтобы правила Disallow покрывали все локализованные варианты путей.

    1. Файл generate-seo.mjs в корне проекта

    generate-seo.mjs
    Копировать код

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

    import fs from "fs";import path from "path";import { fileURLToPath } from "url";import { generateSitemap, getMultilingualUrls } from "intlayer";const __dirname = path.dirname(fileURLToPath(import.meta.url));const SITE_URL = (process.env.SITE_URL || "http://localhost:5173").replace(  /\/$/,  "");const pathList = [  { path: "/", changefreq: "daily", priority: 1.0 },  { path: "/about", changefreq: "monthly", priority: 0.7 },];const sitemapXml = generateSitemap(pathList, { siteUrl: SITE_URL });fs.writeFileSync(path.join(__dirname, "public", "sitemap.xml"), sitemapXml);const getAllMultilingualUrls = (urls) =>  urls.flatMap((url) => Object.values(getMultilingualUrls(url)));const disallowedPaths = getAllMultilingualUrls(["/admin", "/private"]);const robotsTxt = [  "User-agent: *",  "Allow: /",  ...disallowedPaths.map((path) => `Disallow: ${path}`),  "",  `Sitemap: ${SITE_URL}/sitemap.xml`,].join("\n");fs.writeFileSync(path.join(__dirname, "public", "robots.txt"), robotsTxt);console.log("SEO files generated successfully.");

    Пакет intlayer должен быть установлен. Для продакшена задайте SITE_URL в окружении (например в CI).

    Для Node ESM предпочтительно generate-seo.mjs. Для generate-seo.js укажите "type": "module" в package.json или включите ESM иначе.

    2. Запуск скрипта до Vite

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

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

    {  "scripts": {    "dev": "vite",    "prebuild": "node generate-seo.mjs",    "build": "vite build",    "preview": "vite preview"  }}

    Подстройте команды для pnpm или yarn. Скрипт можно вызывать из CI или другого шага.

    Настройка TypeScript

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

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

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

    {  "compilerOptions": {    // ...  },  "include": ["src", ".intlayer/**/*.ts"],}

    Настройка Git

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

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

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

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

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

    Расширение для VS Code

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

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

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

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

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


    Что дальше?

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

    Vite и Preact
    Vite и Lit
    Alt+→

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

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

      npm install intlayer vanilla-intlayernpm install vite-intlayer --save-devnpx intlayer init
      import { installIntlayer } from "vanilla-intlayer";// Должно быть вызвано перед рендерингом любого i18n контента.installIntlayer();// Импортируйте и запустите модули вашего приложения.import "./app.js";
      import { installIntlayer, installIntlayerMarkdown } from "vanilla-intlayer";installIntlayer();installIntlayerMarkdown();import "./app.js";
      import { installIntlayer, useIntlayer } from "vanilla-intlayer";installIntlayer();// Получите начальный контент для текущего языка.// Добавьте .onChange(), чтобы получать уведомления при смене языка.const content = useIntlayer("app").onChange((newContent) => {  // Перерисуйте или обновите только затронутые узлы DOM  document.querySelector<HTMLHeadingElement>("h1")!.textContent = String(    newContent.title  );  document.querySelector<HTMLParagraphElement>(".read-the-docs")!.textContent =    String(newContent.readTheDocs);});// Начальный рендерингdocument.querySelector<HTMLHeadingElement>("h1")!.textContent = String(  content.title);document.querySelector<HTMLParagraphElement>(".read-the-docs")!.textContent =  String(content.readTheDocs);
      img.alt = content.viteLogoLabel.value;
      import { getLocaleName } from "intlayer";import { useLocale } from "vanilla-intlayer";export function setupLocaleSwitcher(container: HTMLElement): () => void {  const { locale, availableLocales, setLocale, subscribe } = useLocale();  const select = document.createElement("select");  select.setAttribute("aria-label", "Language");  const render = (currentLocale: string) => {    select.innerHTML = availableLocales      .map(        (loc) =>          `<option value="${loc}"${loc === currentLocale ? " selected" : ""}>            ${getLocaleName(loc)}          </option>`      )      .join("");  };  render(locale);  container.appendChild(select);  select.addEventListener("change", () => setLocale(select.value as any));  // Синхронизация выпадающего списка при изменении языка из другого места  return subscribe((newLocale) => render(newLocale));}
      import {  compileMarkdown,  installIntlayerMarkdown,  useIntlayer,} from "vanilla-intlayer";installIntlayerMarkdown();const content = useIntlayer("app").onChange((newContent) => {  const el = document.querySelector<HTMLDivElement>(".edit-note")!;  el.innerHTML = compileMarkdown(String(newContent.editNote));});document.querySelector<HTMLDivElement>(".edit-note")!.innerHTML =  compileMarkdown(String(content.editNote));
      import { installIntlayerMarkdownDynamic } from "vanilla-intlayer";await installIntlayerMarkdownDynamic(async () => {  const DOMPurify = await import("dompurify");  return (markdown) => DOMPurify.sanitize(compileMarkdown(markdown));});
      import { installIntlayer, useRewriteURL } from "vanilla-intlayer";installIntlayer();// Перезаписывает URL немедленно и при каждой последующей смене языка.// Возвращает функцию отписки для очистки.const stopRewriteURL = useRewriteURL();
      import { getHTMLTextDir } from "intlayer";import { installIntlayer, useLocale } from "vanilla-intlayer";installIntlayer();useLocale({  onLocaleChange: (locale) => {    document.documentElement.lang = locale;    document.documentElement.dir = getHTMLTextDir(locale);  },});
      import { installIntlayer, useDictionaryDynamic } from "vanilla-intlayer";installIntlayer();const unsubscribe = useDictionaryDynamic(  {    en: () => import("../.intlayer/dictionaries/en/app.mjs"),    fr: () => import("../.intlayer/dictionaries/fr/app.mjs"),    es: () => import("../.intlayer/dictionaries/es/app.mjs"),  },  "app").onChange((content) => {  document.querySelector("h1")!.textContent = String(content.title);});
      import { type IntlayerConfig } from "intlayer";const config: IntlayerConfig = {  // ... Остальная часть вашей конфигурации  compiler: {    /**     * Указывает, должен ли быть включен компилятор.     */    enabled: true,    /**     * Определяет путь к выходным файлам     */    output: ({ fileName, extension }) => `./${fileName}${extension}`,    /**     * Указывает, должны ли компоненты сохраняться после трансформации.     * Таким образом, компилятор можно запустить только один раз для трансформации приложения, а затем удалить его.     */    saveComponents: false,    /**     * Префикс ключа словаря     */    dictionaryKeyPrefix: "",  },};export default config;
      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
      import fs from "fs";import path from "path";import { fileURLToPath } from "url";import { generateSitemap, getMultilingualUrls } from "intlayer";const __dirname = path.dirname(fileURLToPath(import.meta.url));const SITE_URL = (process.env.SITE_URL || "http://localhost:5173").replace(  /\/$/,  "");const pathList = [  { path: "/", changefreq: "daily", priority: 1.0 },  { path: "/about", changefreq: "monthly", priority: 0.7 },];const sitemapXml = generateSitemap(pathList, { siteUrl: SITE_URL });fs.writeFileSync(path.join(__dirname, "public", "sitemap.xml"), sitemapXml);const getAllMultilingualUrls = (urls) =>  urls.flatMap((url) => Object.values(getMultilingualUrls(url)));const disallowedPaths = getAllMultilingualUrls(["/admin", "/private"]);const robotsTxt = [  "User-agent: *",  "Allow: /",  ...disallowedPaths.map((path) => `Disallow: ${path}`),  "",  `Sitemap: ${SITE_URL}/sitemap.xml`,].join("\n");fs.writeFileSync(path.join(__dirname, "public", "robots.txt"), robotsTxt);console.log("SEO files generated successfully.");
      {  "scripts": {    "dev": "vite",    "prebuild": "node generate-seo.mjs",    "build": "vite build",    "preview": "vite preview"  }}
      {  "compilerOptions": {    // ...  },  "include": ["src", ".intlayer/**/*.ts"],}
      # Игнорировать файлы, созданные Intlayer.intlayer