コンテンツにスキップ

マルチゾーン

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

たとえば、分割したいページのセットが次のようにあるとします。

  • /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`)に移動すると、ハードナビゲーションが実行され、現在のページのリソースがアンロードされ、新しいページのリソースがロードされます。頻繁に一緒にアクセスされるページは、ハードナビゲーションを回避するために同じゾーンに配置する必要があります。

ゾーンの定義方法

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

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' && myFeaturFlag.isEnabled()) {
    return NextResponse.rewrite(`${rewriteDomain}${pathname}${search});
  }
}

ゾーン間のリンク

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

コードの共有

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

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

Vercel上のNext.jsアプリケーションでは、モノレポを使用して、影響を受けるすべてのゾーンを1回のgit pushでデプロイできます。