Автор:
    Создание:2026-03-23Последнее обновление:2026-09-27

    Переведите ваш сайт на Vite и Vanilla JS с помощью Intlayer

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

    Содержание

    Почему Intlayer лучше альтернатив?

    По сравнению с основными решениями, такими как i18next или i18n.js, Intlayer это решение, которое включает в себя встроенные оптимизации, такие как:

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

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

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

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

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

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

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

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

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

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

      bash
      npx intlayer init --interactive
      
      флаг --interactive не является обязательным. Используйте intlayer-cli init, если вы являетесь ИИ-агентом.
      Эта команда определит вашу среду и установит необходимые пакеты. Например:
      bash
      npm install intlayer vanilla-intlayer
      npm install vite-intlayer --save-dev
      
      • intlayer Основной пакет, предоставляющий инструменты интернационализации для управления конфигурацией, перевода, объявления контента, транспиляции и команд CLI.

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

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

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

      Архитектура

      В этой архитектуре vanilla-intlayer или ядро intlayer предоставляет API JavaScript для управления переводами и динамического обновления содержимого DOM. Объявления контента находятся в src/.

      bash
      .
      ├── src
      │   ├── app.content.ts
      │   ├── counter.ts
      │   ├── locale-switcher.ts
      │   ├── main.ts                       # Main script using vanilla-intlayer
      │   └── style.css
      ├── index.html
      ├── intlayer.config.ts
      ├── package.json
      ├── tsconfig.json
      └── vite.config.ts
      

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

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

      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({
            proxy: {
              ignore: (req) => req.url?.startsWith("/api"),
            },
          }),
        ],
      });
      
      Плагин 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,md,mdx,yaml,yml}).

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

    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.
      Начиная с Intlayer v9, intlayerProxy() встроен непосредственно в плагин intlayer() и включен по умолчанию через опцию routing.enableProxy (true по умолчанию). Отдельная регистрация, как показано ниже, теперь опциональна, она сохранена для обратной совместимости и для настроек, которым требуется контролировать порядок плагинов. Установите routing.enableProxy: false для отказа. См. заметки выпуска v9.
      vite.config.ts
      import { defineConfig } from "vite";
      import { intlayer } from "vite-intlayer";
      
      export default defineConfig({
        plugins: [
          intlayer({
            proxy: {
              ignore: (req) => req.url?.startsWith("/api"),
            },
          }),
        ],
      });
      
    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
      
      Since v9, the intlayerCompiler is included in the intlayer plugin. So you don't need to add it manually.

      Обновите vite.config.ts, включив плагин intlayerCompiler:

      vite.config.ts
      import { defineConfig } from "vite";
      import { intlayer, intlayerCompiler } from "vite-intlayer";
      
      export default defineConfig({
        plugins: [
          intlayer(),
          intlayerCompiler(), // Adds the compiler plugin
        ],
      });
      

      Соберите приложение, чтобы преобразовать ваши компоненты и извлечь контент

      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: "https://example.com",
    });
    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: https://example.com/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.

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

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

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

    Что дальше?

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

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

    У Vite нет мнения об i18n, поэтому выбор идёт из экосистемы Vanilla JS:

    • Написанный вручную объект-словарь, импортируемый в вашу точку входа: без зависимостей, но без типизации, без правил множественного числа и без чего-либо, что сообщит вам о недостающем переводе.
    • i18next: зрелый и независимый от фреймворка, но он добавляет среду выполнения и загружает каталоги как JSON.
    • Intlayer: контент, объявленный рядом с каждым компонентом и скомпилированный плагином Vite во время сборки, полностью типизированный, с ИИ-переводом, визуальным редактором и CMS.

    Специфичный для Vite выигрыш в том, что переводы разрешаются и подвергаются tree-shaking во время компиляции, а не загружаются как JSON во время выполнения, поэтому страница поставляет только те записи, которые отображает. См. почему Intlayer и бенчмарк.

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

    В значительной степени. Следуйте руководству по миграции с i18next, чтобы перенести контент. Вы также можете мигрировать постепенно: плагин синхронизации JSON сохраняет ваши существующие каталоги JSON как источник истины и генерирует из них словари Intlayer, поэтому оба слоя остаются синхронизированными, пока вы переносите модули по одному.

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

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

    Для полностью автоматизированного конвейера Компилятор 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 помечает жёстко закодированные строки, с дополнительными правилами для статических ключей словаря и неиспользуемого контента.