著者:
    作成:2026-03-23最終更新:2026-06-23

    Intlayerを使用したViteおよびVanilla JSウェブサイトの翻訳 | 国際化 (i18n)

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

    目次

    代替手段ではなく Interlayer を使用する理由

    「i18next」や「i18n.js」などの主要なソリューションと比較して、Intlayer は次のような統合された最適化を備えたソリューションです。

    Vite の完全な内容

    Intlayer は、フレームワークに依存しないコンテンツ管理TypeScript サポート、および国際化の拡張 (i18n) に必要なすべての機能を提供することで、Vite と完全に連携するように最適化されています。

    バンドルサイズ

    大量の JSON ファイルをページにロードするのではなく、必要なコンテンツのみをロードします。 Intlayer は、バンドルとページのサイズを最大 50% 削減するのに役立ちます。

    保守性

    アプリケーションのコンテンツのスコープを設定すると、大規模なアプリケーションの メンテナンスが容易になります。コンテンツ コードベース全体を確認するという精神的な負担を負うことなく、単一の機能フォルダーを複製または削除できます。さらに、Intlayer は完全に型指定されており、コンテンツの正確性を保証します。

    AI エージェント

    コンテンツを同じ場所に配置すると、大規模言語モデル (LLM) によって 必要なコンテキストが削減されます。 Intlayer には、翻訳の欠落をテストする CLILSPMCP などのツール スイートも付属しています。および agent skills により、AI エージェントの開発者エクスペリエンス (DX) がさらにスムーズになります。

    オートメーション

    AI プロバイダーの費用で、選択した LLM を使用して CI/CD パイプラインで自動化を変換します。 Intlayer は、コンテンツ抽出を自動化する コンパイラー と、バックグラウンドでの翻訳を支援する Web プラットフォーム も提供します。

    パフォーマンス

    大量の JSON ファイルをコンポーネントに接続すると、パフォーマンスと反応性の問題が発生する可能性があります。 Intlayer は、ビルド時のコンテンツの読み込みを最適化します。

    非開発によるスケーリング

    Intlayer は単なる i18n ソリューションではなく、自己ホスト型 ビジュアル エディター完全な CMS を提供します。 リアルタイムで多言語コンテンツを管理できるようになり、翻訳者、コピーライター、その他のチーム メンバーとのコラボレーションがシームレスになります。コンテンツはローカルおよび/またはリモートに保存できます。

    </AccordionGroup>


    ViteおよびVanilla JSアプリケーションでIntlayerをセットアップするためのステップバイステップガイド

    1. 依存関係のインストール

      npmを使用して必要なパッケージをインストールします:

      bash
      npx intlayer init --interactive
      
      --interactive フラグはオプションです。AI エージェントの場合は intlayer-cli init を使用してください。
      このコマンドは環境を検出し、必要なパッケージをインストールします。例えば:
      bash
      npm install intlayer vanilla-intlayer
      npm install vite-intlayer --save-dev
      
      • intlayer 設定管理、翻訳、コンテンツ宣言、トランスパイル、およびCLIコマンドのための国際化ツールを提供するコアパッケージ。

      • vanilla-intlayer Intlayerを純粋なJavaScript / TypeScriptアプリケーションと統合するパッケージ。パブリッシュ/サブスクライブ シングルトン (IntlayerClient) とコールバックベースのヘルパー (useIntlayeruseLocaleなど) を提供し、UIフレームワークに依存せずにアプリのどこからでも言語の変更に反応できるようにします。

      • vite-intlayer Intlayerを[Vite バンドラー](https://vite.dev/guide/why.html Japan#why-bundle-for-production)と統合するためのViteプラグイン、およびユーザーの優先言語の検出、クッキーの管理、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. Vite設定へのIntlayerの統合

      設定に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"),
            },
          }),
        ],
      });
      
      intlayer() Viteプラグインは、IntlayerをViteと統合するために使用されます。コンテンツ宣言ファイルの構築を確実にし、開発モードでそれらを監視します。Viteアプリケーション内でIntlayer環境変数を定義します。さらに、パフォーマンスを最適化するためのエイリアスを提供します。
    4. エントリーポイントでのIntlayerのブートストラップ

      グローバルな言語シングルトンの準備ができるように、コンテンツがレンダリングされるinstallIntlayer() を呼び出します。

      src/main.ts
      import { installIntlayer } from "vanilla-intlayer";
      
      // i18nコンテンツをレンダリングする前に呼び出す必要があります。
      installIntlayer();
      
      // アプリケーションモジュールをインポートして実行。
      import "./app.js";
      

      md() コンテンツ宣言(Markdown)も使用する場合は、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. JavaScriptでのIntlayerの使用

      vanilla-intlayerreact-intlayer のサーフェスAPIを反映しています:useIntlayer(key, locale?) は翻訳されたコンテンツを直接返します。結果に対して .onChange() をチェーンして言語の変更を購読します(これはReactの再レンダリングと同じ明示的な効果を持ちます)。

      src/main.ts
      import { installIntlayer, useIntlayer } from "vanilla-intlayer";
      
      installIntlayer();
      
      // 現在の言語の初期コンテンツを取得。
      // 言語が変更されるたびに通知を受け取るために .onChange() をチェーン。
      const content = useIntlayer("app").onChange((newContent) => {
        // 影響を受けるドームノードのみを再レンダリングまたはパッチ
        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属性の属性値(例:altaria-label)が必要な場合は、.value を直接使用してください。

      typescript
      img.alt = content.viteLogoLabel.value;
      
    7. コンテンツの言語を変更する

      オプション

      コンテンツの言語を変更するには、useLocale によって公開される setLocale 関数を使用します。

      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() コンテンツ宣言をサポートしています。Vanilla JSでは、コンパイルされた出力は innerHTML を介して生のHTMLとして挿入されます。

      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) は、生のMarkdown文字列を返す IntlayerNode 上で toString() を呼び出します。これを compileMarkdown に渡してHTML文字列を取得し、innerHTML を介して設定します。
      WARNING

      信頼できるコンテンツに対してのみ innerHTML を使用してください。Markdownがユーザー入力から来ている場合は、最初にサニタイズしてください(例:DOMPurifyを使用)。サニタイズレンダラーを動的にインストールできます:

      typescript
      import { installIntlayerMarkdownDynamic } from "vanilla-intlayer";
      
      await installIntlayerMarkdownDynamic(async () => {
        const DOMPurify = await import("dompurify");
        return (markdown) => DOMPurify.sanitize(compileMarkdown(markdown));
      });
      
    9. アプリケーションへのローカライズされたルーティングの追加

      オプション

      言語ごとにユニークなルートを作成するには(SEOに有用)、Vite設定で intlayerProxy を使用してサーバーサイドの言語検出を行うことができます。

      まず、Vite設定に intlayerProxy を追加します。

      本番環境で intlayerProxy を使用するには、vite-intlayerdevDependencies から 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を更新するには、Intlayerのインストール後に useRewriteURL() を呼び出します。

      src/main.ts
      import { installIntlayer, useRewriteURL } from "vanilla-intlayer";
      
      installIntlayer();
      
      // すぐに、およびその後のすべての言語変更時にURLを書き換えます。
      // クリーンアップのための購読停止関数を返します。
      const stopRewriteURL = useRewriteURL();
      
    11. HTML 言語属性とテキスト方向属性の切り替え

      オプション

      アクセシビリティとSEOのために、<html> タグの lang および dir 属性を現在の言語に合わせて更新します。

      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. 言語ごとの辞書の遅延ロード

      オプション

      大規模なアプリの場合、各言語の辞書を独自のチャンクに分割したい場合があります。Viteの動的 import() と併せて useDictionaryDynamic を使用します:

      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はコンポーネントを変換してコンテンツを抽出するための コンパイラ / エクストラクター を提案しています。

      セットアップするには、intlayer.config.ts ファイルに compiler セクションを追加します。

      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.

      intlayerCompiler プラグインを含めるように vite.config.ts を更新します:

      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
      

    (任意)サイトマップと robots.txt(ビルド時生成)

    Intlayer は generateSitemapgetMultilingualUrls により、クローラ向けに整形した多言語の sitemap.xmlrobots.txtpublic/ に自動で書き出せます。通常は Vite よりに小さな Node スクリプトを走らせます(例: npm の predev / prebuild)。

    サイトマップ

    Intlayer のサイトマップ生成はロケール設定を踏まえ、クローラ向けのメタデータを含めます。

    生成されるサイトマップは xhtml:link(hreflang)をサポートします。単純な URL 列挙ではなく、各ページの言語版同士を双方向で結びます(例: /about/fr/about/about?lang=fr などルーティングに依存)。

    Robots.txt

    getMultilingualUrlsDisallow を、機微パスのすべての言語 URLに効かせます。

    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 にする場合は package.json"type": "module" などで 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を使用してコンテンツを外部化したりできます。