Creation:2026-03-23Last update:2026-05-06

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

    ide.intlayer.org

    Содержание

    Что такое 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

    (Опционально) 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.