コンテンツへスキップ

マルチゾーン

マルチゾーンは、ドメイン上の大規模なアプリケーションを、それぞれがパスのセットを提供するより小さなNext.jsアプリケーションに分割するマイクロフロントエンドのアプローチです。これは、アプリケーション内の他のページとは無関係なページの集まりがある場合に役立ちます。これらのページを別のゾーン(つまり、別のアプリケーション)に移動することで、各アプリケーションのサイズを削減し、ビルド時間を改善し、特定のゾーンにのみ必要なコードを削除できます。アプリケーションが分離されているため、マルチゾーンは、ドメイン上の他のアプリケーションが独自のフレームワークを選択することを可能にします。

たとえば、以下のようなページセットを分割したいとします。

  • すべてのブログ記事用の/blog/*
  • ユーザーがダッシュボードにログインしている場合のすべてのページ用の/dashboard/*
  • 他のゾーンでカバーされていない残りのウェブサイト用の/*

マルチゾーンのサポートにより、同じドメインで提供され、ユーザーには同じように見える3つのアプリケーションを作成できますが、それぞれのアプリケーションを独立して開発およびデプロイできます。

Three zones: A, B, C. Showing a hard navigation between routes from different zones, and soft navigations between routes within the same zone.

同じゾーン内のページ間を移動すると、ソフトナビゲーション(ページの再読み込みを必要としないナビゲーション)が実行されます。たとえば、この図では、/から/productsへの移動はソフトナビゲーションになります。

あるゾーンのページから別のゾーンのページ(たとえば/から/dashboard)に移動すると、ハードナビゲーション(現在のページのリソースをアンロードし、新しいページのリソースをロードする)が実行されます。頻繁に一緒にアクセスされるページは、ハードナビゲーションを避けるために同じゾーン内に配置する必要があります。

ゾーンの定義方法

ゾーンは通常のNext.jsアプリケーションであり、他のゾーンのページや静的ファイルとの競合を避けるためにassetPrefixも設定します。

next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  assetPrefix: '/blog-static',
}

JavaScriptやCSSなどのNext.jsアセットには、他のゾーンのアセットと競合しないようにassetPrefixが付加されます。これらのアセットは、各ゾーンの/assetPrefix/_next/...の下で提供されます。

より具体的な別のゾーンにルーティングされないすべてのパスを処理するデフォルトアプリケーションは、assetPrefixを必要としません。

Next.js 15より前のバージョンでは、静的アセットを処理するために追加のリライトが必要になる場合がありました。Next.js 15ではこれは不要になりました。

next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  assetPrefix: '/blog-static',
  async rewrites() {
    return {
      beforeFiles: [
        {
          source: '/blog-static/_next/:path+',
          destination: '/_next/:path+',
        },
      ],
    }
  },
}

正しいゾーンへのリクエストのルーティング方法

マルチゾーンの設定では、パスは異なるアプリケーションによって提供されるため、正しいゾーンにルーティングする必要があります。これには任意のHTTPプロキシを使用できますが、Next.jsアプリケーションの1つをドメイン全体のリクエストをルーティングするために使用することもできます。

Next.jsアプリケーションを使用して正しいゾーンにルーティングするには、rewritesを使用できます。異なるゾーンによって提供されるパスごとに、そのパスを他のゾーンのドメインに送信するリライトルールを追加します。例えば、

next.config.js
async rewrites() {
    return [
        {
            source: '/blog',
            destination: `${process.env.BLOG_DOMAIN}/blog`,
        },
        {
            source: '/blog/:path+',
            destination: `${process.env.BLOG_DOMAIN}/blog/:path+`,
        }
    ];
}

destinationは、スキームとドメインを含む、ゾーンによって提供されるURLである必要があります。これはゾーンのプロダクションドメインを指すべきですが、ローカル開発ではlocalhostへのリクエストをルーティングするためにも使用できます。

知っておくと便利: URLパスはゾーンごとに一意である必要があります。たとえば、2つのゾーンが/blogを提供しようとすると、ルーティングの競合が発生します。

ミドルウェアを使用したリクエストのルーティング

リクエストのレイテンシオーバーヘッドを最小限に抑えるには、rewritesを介したリクエストのルーティングが推奨されますが、ルーティング時に動的な決定が必要な場合はミドルウェアも使用できます。たとえば、移行中にパスのルーティング先を決定するためにフィーチャーフラグを使用している場合、ミドルウェアを使用できます。

middleware.js
export async function middleware(request) {
  const { pathname, search } = req.nextUrl;
  if (pathname === '/your-path' && myFeatureFlag.isEnabled()) {
    return NextResponse.rewrite(`${rewriteDomain}${pathname}${search});
  }
}

ゾーン間のリンク

異なるゾーンのパスへのリンクは、Next.jsの<Link>コンポーネントではなくaタグを使用する必要があります。これは、Next.jsが<Link>コンポーネント内の任意の相対パスをプリフェッチしてソフトナビゲーションしようとし、それがゾーン間では機能しないためです。

コードの共有

異なるゾーンを構成するNext.jsアプリケーションは、どのリポジトリにも配置できます。ただし、コードをより簡単に共有するために、これらのゾーンをモノレポに配置すると便利な場合が多いです。異なるリポジトリに存在するゾーンの場合、コードは公開またはプライベートなNPMパッケージを使用して共有することもできます。

異なるゾーンのページは異なるタイミングでリリースされる可能性があるため、異なるゾーン間で機能を一斉に有効または無効にするには、フィーチャーフラグが役立ちます。

Vercel上のNext.jsアプリケーションの場合、単一のgit pushで影響を受けるすべてのゾーンをデプロイするためにモノレポを使用できます。

サーバーアクション

マルチゾーンでサーバーアクションを使用する場合、ユーザーに表示されるドメインが複数のアプリケーションを提供する可能性があるため、ユーザーに表示されるオリジンを明示的に許可する必要があります。next.config.jsファイルに以下の行を追加してください。

next.config.js
const nextConfig = {
  experimental: {
    serverActions: {
      allowedOrigins: ['your-production-domain.com'],
    },
  },
}

詳細については、serverActions.allowedOriginsを参照してください。