メインコンテンツまでスキップ

Multi-Zones

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

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

  • /blog/* すべてのブログ投稿
  • /dashboard/* ダッシュボードにログインしているときのすべてのページ
  • /* 他のゾーンでカバーされていないWebサイトの残りの部分

Multi-Zonesサポートを使用すると、ユーザーに同じように見える同じドメインで提供される3つのアプリケーションを作成できますが、各アプリケーションを独立して開発およびデプロイできます。

三つのゾーン:A、B、C。他のゾーンからのルートへのハードナビゲーションと、同じゾーン内のルート間のソフトナビゲーションを示す示唆。三つのゾーン:A、B、C。他のゾーンからのルートへのハードナビゲーションと、同じゾーン内のルート間のソフトナビゲーションを示す示唆。

同じゾーン内のページ間をナビゲートすると、ページのリロードを必要としないソフトナビゲーションが実行されます。たとえば、この図では、/から/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+',
},
],
}
},
}

リクエストを適切なゾーンにルーティングする方法

Multi-Zonesセットアップでは、異なるアプリケーションで提供されるため、パスを正しいゾーンにルーティングする必要があります。これを行うには、任意の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にルーティングするのにも使用できます。

Good to know: 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アプリケーションは、任意のリポジトリに存在することができます。ただし、コードをより簡単に共有するために、これらのゾーンをmonorepoに配置することがよくあります。異なるリポジトリにあるゾーンについては、パブリックまたはプライベートのNPMパッケージを使用してコードを共有することもできます。

異なるタイミングでリリースされる可能性があるため、異なるゾーン間で機能を一斉に有効化または無効化するために機能フラグが役立つことがあります。

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

Server Actions

Multi-Zonesを使用する際にServer Actionsを使用する場合は、ユーザーフェーシングのオリジンを明示的に許可しなければなりません。なぜなら、ユーザーフェーシングのドメインが複数のアプリケーションを提供する可能性があるからです。next.config.jsファイルに次の行を追加します:

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

詳細はserverActions.allowedOriginsをご覧ください。