コンテンツにスキップ
App Routerガイドマルチゾーン

マルチゾーンとNext.jsを使用したマイクロフロントエンドの構築方法

マルチゾーンは、ドメイン上の大規模なアプリケーションを、それぞれパスのセットを提供する小さな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への移動はソフトナビゲーションになります。

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

ゾーンの定義方法

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

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

Next.jsのJavaScriptやCSSなどのアセットは、他のゾーンのアセットと競合しないように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アプリケーションのいずれかを使用することもできます。

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+`,
        },
        {
            source: '/blog-static/:path+',
            destination: `${process.env.BLOG_DOMAIN}/blog-static/:path+`,
        }
    ];
}

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

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

プロキシを使用したリクエストのルーティング

リクエストのレイテンシオーバーヘッドを最小限に抑えるには、rewritesを介してリクエストをルーティングすることをお勧めしますが、ルーティング時に動的な決定が必要な場合はプロキシを使用することもできます。たとえば、機能フラグを使用してパスをどこにルーティングするか(移行中など)を決定している場合、プロキシを使用できます。

proxy.js
export async function proxy(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パッケージを使用してコードを共有することもできます。

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

サーバーアクション

マルチゾーンでServer Actionsを使用する場合、ユーザーが直面するドメインが複数のアプリケーションを提供する可能性があるため、ユーザーが直面するオリジンを明示的に許可する必要があります。next.config.jsファイルに次の行を追加します。

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

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