作成:2026-04-02最終更新:2026-04-02

    カスタムドメイン

    Intlayerはドメインベースのロケールルーティングをサポートしており、専用のホスト名から特定のロケールを提供できます。たとえば、中国の訪問者を intlayer.org/zh ではなく intlayer.zh に誘導できます。

    仕組み

    routingdomains マップは、各ロケールをホスト名に関連付けます。Intlayerはこのマップを次の2か所で使用します。

    1. URLの生成 (getLocalizedUrl): ターゲットのロケールが現在のページとは 異なる ドメインにある場合、絶対URLが返されます(例: https://intlayer.zh/about)。両方のドメインが一致する場合、相対URLが返されます(例: /fr/about)。
    2. サーバープロキシ(Next.js & Vite): 着信リクエストは、到着したドメインに基づいてリダイレクトまたはリライトされます。

    排他的ドメイン vs 共有ドメイン

    主な違いは 排他性 です。

    • 排他的ドメイン - 1つのロケールのみがそのホスト名にマップされます(例: zh → intlayer.zh)。ドメイン自体がロケールを識別するため、パスにロケールプレフィックスは追加されません。 https://intlayer.zh/about は中国語のコンテンツを提供します。
    • 共有ドメイン - 複数のロケールが同じホスト名にマップされます(例: enfr の両方が intlayer.org にマップされます)。通常のプレフィックスベースのルーティングが適用されます。 intlayer.org/fr/about はフランス語のコンテンツを提供します。

    設定

    import { Locales, type IntlayerConfig } from "intlayer";
    
    const config: IntlayerConfig = {
      internationalization: {
        locales: [
          Locales.ENGLISH,
          Locales.FRENCH,
          Locales.SPANISH,
          Locales.CHINESE,
        ],
        defaultLocale: Locales.ENGLISH,
      },
      routing: {
        mode: "prefix-no-default",
        domains: {
          // 共有ドメイン - enとfrはintlayer.orgでプレフィックスルーティングを使用
          en: "intlayer.org",
          // 排他的ドメイン - zhは独自のホスト名を持ち、/zh/プレフィックスは不要
          zh: "intlayer.zh",
        },
      },
    };
    
    export default config;

    domains にリストされていないロケールは、ドメインの上書きなしで標準のプレフィックスルーティングを引き続き使用します。

    URLの生成

    getLocalizedUrl は、呼び出しコンテキストに基づいて正しいURLタイプを自動的に生成します。

    同一ドメインのロケール(相対URL)

    // 現在のページ: intlayer.org/about
    getLocalizedUrl("/about", "fr", { currentDomain: "intlayer.org" });
    // → "/fr/about"
    
    getLocalizedUrl("/about", "en", { currentDomain: "intlayer.org" });
    // → "/about" (デフォルトのロケール、プレフィックスなし)

    ドメインをまたぐロケール(絶対URL)

    // 現在のページ: intlayer.org/about
    getLocalizedUrl("/about", "zh", { currentDomain: "intlayer.org" });
    // → "https://intlayer.zh/about" (排他的ドメイン、/zh/プレフィックスなし)

    ロケール自身のドメインからの提供

    // 現在のページ: intlayer.zh/about
    getLocalizedUrl("/about", "zh", { currentDomain: "intlayer.zh" });
    // → "/about" (すでに正しいドメイン上にある - 相対URL)
    
    getLocalizedUrl("/about", "fr", { currentDomain: "intlayer.zh" });
    // → "https://intlayer.org/fr/about" (intlayer.orgへのドメイン間リンク)

    現在のドメインの自動検出

    currentDomain はオプションです。省略した場合、 getLocalizedUrl は次の順序で解決します。

    1. 絶対入力URLのホスト名(例: https://intlayer.org/aboutintlayer.org)。
    2. ブラウザ環境における window.location.hostname
    3. いずれも利用できない場合(明示的なオプションなしのSSR)、同一ドメインのロケールに対して相対URLが返され、絶対URLは生成されません。これが安全なフォールバックです。
    // ブラウザ - window.location.hostname === 'intlayer.org'
    getLocalizedUrl("/about", "zh");
    // → "https://intlayer.zh/about" (windowから自動検出)
    
    // 絶対URLから - ドメインを自動検出
    getLocalizedUrl("https://intlayer.org/about", "zh");
    // → "https://intlayer.zh/about"

    ドメインを使用した getMultilingualUrls

    getMultilingualUrls はすべてのロケールに対して getLocalizedUrl を呼び出すため、呼び出し元のドメインに応じて相対URLと絶対URLが混在して生成されます。

    // currentDomain: 'intlayer.org'
    getMultilingualUrls("/about", { currentDomain: "intlayer.org" });
    // {
    //   en: "/about",
    //   fr: "/fr/about",
    //   es: "/es/about",
    //   zh: "https://intlayer.zh/about",
    // }

    これらの絶対URLは、SEO用の <link rel="alternate" hreflang="..."> タグですぐに使用できます。

    プロキシの動作

    Next.js

    intlayerProxy ミドルウェアはドメインルーティングを自動的に処理します。 middleware.ts に追加してください。

    export { intlayerProxy as default } from "next-intlayer/proxy";
    
    export const config = {
      matcher: "/((?!api|static|assets|robots|sitemap|.*\\..*|_next).*)",
    };

    リダイレクト - 指定されたロケールプレフィックスに対してリクエストが間違ったドメインに到着した場合:

    GET intlayer.org/zh/about
    → 301 https://intlayer.zh/about

    リライト - プレフィックスなしでロケールの排他的ドメインにリクエストが到着した場合:

    GET intlayer.zh/about
    → /zh/about へのリライト(Next.jsの内部ルーティングのみ、URLはきれいなまま)

    Vite

    intlayerProxy Viteプラグインは、開発中に同じロジックを適用します。

    import { defineConfig } from "vite";
    import { intlayerProxy } from "vite-intlayer";
    
    export default defineConfig({
      plugins: [intlayerProxy()],
    });
    注意: ローカル開発では通常 localhost 上にいるため、ドメイン間のリダイレクトは別のローカルポートではなくライブドメインを指します。マルチドメインルーティングをローカルでテストする必要がある場合は、hostsファイルの上書き(例: 127.0.0.1 intlayer.zh)またはリバースプロキシを使用してください。

    ロケールスイッチャー

    next-intlayeruseLocale フックは、ドメインを認識したナビゲーションを自動的に処理します。ユーザーが別のドメインのロケールに切り替えると、Next.jsルーターはオリジンを越えることができないため、フックはクライアント側のルータープッシュではなく、フルページナビゲーション( window.location.href )を実行します。

    "use client";
    
    import { useLocale } from "next-intlayer";
    
    export const LocaleSwitcher = () => {
      const { availableLocales, locale, setLocale } = useLocale();
    
      return (
        <ul>
          {availableLocales.map((localeEl) => (
            <li key={localeEl}>
              <button
                onClick={() => setLocale(localeEl)}
                aria-current={localeEl === locale ? "true" : undefined}
              >
                {l.toUpperCase()}
              </button>
            </li>
          ))}
        </ul>
      );
    };

    追加の設定は不要です。 useLocale は内部的に window.location.hostname を検出し、 router.replace (同一ドメイン)と window.location.href (ドメイン間)のどちらかを選択します。

    SEO: hreflang 代替リンク

    ドメインベースのルーティングは、検索エンジンに各言語でインデックスを作成するURLを伝えるために、 hreflang と共に一般的に使用されます。 getMultilingualUrls を使用して、代替URLの完全なセットを生成します。

    import { getMultilingualUrls } from "intlayer";
    import type { Metadata } from "next";
    
    export const generateMetadata = (): Metadata => {
      const alternates = getMultilingualUrls("/", {
        currentDomain: process.env.NEXT_PUBLIC_DOMAIN, // 例: "intlayer.org"
      });
    
      return {
        alternates: {
          languages: alternates,
        },
      };
    };

    これにより、以下が生成されます。

    <link rel="alternate" hreflang="en" href="https://intlayer.org/" />
    <link rel="alternate" hreflang="fr" href="https://intlayer.org/fr/" />
    <link rel="alternate" hreflang="es" href="https://intlayer.org/es/" />
    <link rel="alternate" hreflang="zh" href="https://intlayer.zh/" />

    コアユーティリティ

    ユーティリティ 説明
    getLocalizedUrl(url, locale, { currentDomain }) ターゲットロケールが現在のドメインにあるかどうかに応じて、相対URLまたは絶対URLを返します。
    getMultilingualUrls(url, { currentDomain }) 必要に応じて相対URLと絶対URLを混合し、ロケールをキーとしたローカライズ済みURLのマップを返します。
    getPrefix(locale, { domains }) 排他的ドメインのロケールには空のプレフィックスを返し、それ以外の場合は通常のプレフィックスを返します。