パラレルルート (Parallel Routes)
パラレルルート (Parallel Routes) を使用すると、同じレイアウト内で複数のページを同時または条件付きでレンダリングできます。ダッシュボードやソーシャルサイトのフィードなど、アプリの高度に動的なセクションに有用です。
例えば、ダッシュボードで team
と analytics
ページを同時にレンダリングする場合:

規約
スロット
パラレルルートは名前付き スロット を使用して作成されます。スロットは @folder
規約で定義します。例えば、以下のファイル構造では @analytics
と @team
の2つのスロットが定義されています:

スロットは共有親レイアウトにプロップスとして渡されます。上記の例では、app/layout.js
のコンポーネントが @analytics
と @team
スロットのプロップスを受け取り、children
プロップスと並行してレンダリングできます:
ただし、スロットはルートセグメント ではなく、URL構造に影響しません。例えば、/@analytics/views
の場合、URLは @analytics
がスロットであるため /views
になります。スロットは通常のページコンポーネントと組み合わされて、ルートセグメントに関連付けられた最終的なページを形成します。このため、同じルートセグメントレベルで静的と動的のスロットを同時に持つことはできません。1つのスロットが動的である場合、そのレベルのすべてのスロットは動的でなければなりません。
知っておくと便利:
children
プロップスはフォルダにマッピングする必要のない暗黙的なスロットです。つまり、app/page.js
はapp/@children/page.js
と同等です。
default.js
初期ロードまたはフルページリロード時に、マッチしないスロットのフォールバックとしてレンダリングする default.js
ファイルを定義できます。
以下のフォルダ構造を考えてみましょう。@team
スロットには /settings
ページがありますが、@analytics
にはありません。

/settings
にナビゲートすると、@team
スロットは /settings
ページをレンダリングし、@analytics
スロットの現在アクティブなページを維持します。
リフレッシュ時、Next.js は @analytics
に対して default.js
をレンダリングします。default.js
が存在しない場合、代わりに 404
がレンダリングされます。
さらに、children
は暗黙的なスロットであるため、Next.js が親ページのアクティブな状態を回復できない場合に children
のフォールバックをレンダリングするためにも default.js
ファイルを作成する必要があります。
動作
デフォルトでは、Next.js は各スロットのアクティブな 状態 (またはサブページ) を追跡します。ただし、スロット内でレンダリングされるコンテンツはナビゲーションのタイプによって異なります:
- ソフトナビゲーション: クライアントサイドナビゲーション時、Next.js は部分レンダリングを実行し、スロット内のサブページを変更しながら、他のスロットのアクティブなサブページを維持します(現在のURLと一致しなくても)。
- ハードナビゲーション: フルページロード(ブラウザリフレッシュ)後、Next.js は現在のURLと一致しないスロットのアクティブな状態を決定できません。代わりに、マッチしないスロットに対して
default.js
ファイルをレンダリングし、default.js
が存在しない場合は404
をレンダリングします。
知っておくと便利:
- マッチしないルートに対する
404
は、意図しないページでパラレルルートを誤ってレンダリングしないようにするのに役立ちます。
例
useSelectedLayoutSegment(s)
の使用
useSelectedLayoutSegment
と useSelectedLayoutSegments
はどちらも parallelRoutesKey
パラメータを受け取り、スロット内のアクティブルートセグメントを読み取ることができます。
ユーザーが app/@auth/login
(またはURLバーで /login
)にナビゲートすると、loginSegment
は文字列 "login"
と等しくなります。
条件付きルート
パラレルルートを使用して、ユーザーロールなどの条件に基づいてルートを条件付きでレンダリングできます。例えば、/admin
または /user
ロールに対して異なるダッシュボードページをレンダリングする場合:

タブグループ
スロット内に layout
を追加して、ユーザーがスロットを独立してナビゲートできるようにできます。これはタブを作成するのに便利です。
例えば、@analytics
スロットには /page-views
と /visitors
の2つのサブページがあります。

@analytics
内に layout
ファイルを作成し、2つのページ間でタブを共有します:
モーダル
パラレルルートはインターセプトルートと組み合わせて、ディープリンクをサポートするモーダルを作成できます。これにより、モーダル構築時の一般的な課題を解決できます:
- モーダルコンテンツを URLを通じて共有可能 にする
- ページがリフレッシュされたときに コンテキストを保持 し、モーダルを閉じない
- 戻るナビゲーションで モーダルを閉じ、前のルートに移動しない
- 進むナビゲーションで モーダルを再開 する
クライアントサイドナビゲーションを使用してレイアウトからログインモーダルを開くか、別の /login
ページにアクセスできるUIパターンを考えてみましょう:

このパターンを実装するには、まず メイン ログインページをレンダリングする /login
ルートを作成します。

次に、@auth
スロット内に null
を返す default.js
ファイルを追加します。これにより、モーダルがアクティブでないときにレンダリングされなくなります。
@auth
スロット内で、/(.)login
フォルダを更新して /login
ルートをインターセプトします。<Modal>
コンポーネントとその子を /(.)login/page.tsx
ファイルにインポートします:
知っておくと便利:
- ルートをインターセプトするために使用される規約(例:
(.)
)は、ファイルシステム構造によって異なります。インターセプトルート規約を参照してください。- モーダル機能(
<Modal>
)をモーダルコンテンツ(<Login>
)から分離することで、モーダル内のコンテンツ(例: フォーム)がサーバーコンポーネントであることを保証できます。クライアントとサーバーコンポーネントの交互配置を参照してください。
モーダルを開く
Next.jsルーターを活用してモーダルを開閉できます。これにより、モーダルが開いているときや前後にナビゲートするときにURLが正しく更新されます。
モーダルを開くには、@auth
スロットを親レイアウトにプロップスとして渡し、children
プロップスと一緒にレンダリングします。
ユーザーが <Link>
をクリックすると、/login
ページに移動する代わりにモーダルが開きます。ただし、リフレッシュ時や初期ロード時には、/login
に移動するとメインのログインページが表示されます。
モーダルを閉じる
router.back()
を呼び出すか、Link
コンポーネントを使用してモーダルを閉じることができます。
@auth
スロットをレンダリングすべきでないページから離れるために Link
コンポーネントを使用する場合、null
を返すコンポーネントにパラレルルートがマッチするようにする必要があります。例えば、ルートページに戻る場合、@auth/page.tsx
コンポーネントを作成します:
または、他のページ(/foo
、/foo/bar
など)にナビゲートする場合、キャッチオールスロットを使用できます:
知っておくと便利:
- モーダルを閉じるために
@auth
スロットでキャッチオールルートを使用するのは、パラレルルートの動作(#behavior)によるものです。スロットにマッチしなくなったルートへのクライアントサイドナビゲーションは表示されたままになるため、モーダルを閉じるにはnull
を返すルートにマッチさせる必要があります。- 他の例としては、ギャラリーで写真モーダルを開きながら専用の
/photo/[id]
ページを持つことや、サイドモーダルでショッピングカートを開くことが含まれます。- インターセプトとパラレルルートを使用したモーダルの例を参照してください。
ローディングとエラーUI
パラレルルートは独立してストリーミングできるため、各ルートに対して独立したエラーとローディング状態を定義できます:
