並列ルート
並列ルートを使用すると、同じレイアウト内で1つ以上のページを同時または条件付きでレンダリングできます。ソーシャルサイトのダッシュボードやフィードなど、アプリの高度に動的なセクションに便利です。
例えば、ダッシュボードを考えると、並列ルートを使用してteam
とanalytics
ページを同時にレンダリングできます:
スロット
並列ルートは、名前付きのスロットを使用して作成されます。スロットは@folder
規則で定義されます。例えば、次のファイル構造は@analytics
と@team
の2つのスロットを定義しています:
スロットは共通の親レイアウトにプロップとして渡されます。上記の例では、app/layout.js
のコンポーネントが@analytics
と@team
スロットのプロップを受け取り、children
プロップと並行してそれらをレンダリングできます:
ただし、スロットはルートセグメントではなく、URL構造に影響しません。例えば、/@analytics/views
の場合、URLは/views
になります。これは@analytics
がスロットであるためです。スロットは通常のPageコンポーネントと組み合わせて、ルートセグメントに関連付けられた最終的なページを形成します。このため、同じルートセグメントレベルで異なる静的および動的スロットを持つことはできません。1つのスロットが動的な場合、そのレベルのすべてのスロットは動的である必要があります。
補足:
children
プロップは、フォルダにマッピングする必要のない暗黙のスロットです。つまり、app/page.js
はapp/@children/page.js
と同等です。
アクティブ状態とナビゲーション
デフォルトでは、Next.jsは各スロットのアクティブな_状態_(またはサブページ)を追跡します。ただし、スロット内でレンダリングされるコンテンツは、ナビゲーションの種類によって異なります:
- ソフトナビゲーション:クライアントサイドのナビゲーション中、Next.jsは部分的なレンダリングを実行し、他のスロットのアクティブなサブページを維持しながら、スロット内のサブページを変更します。
- ハードナビゲーション:完全なページロード(ブラウザ更新)後、Next.jsは現在のURLと一致しないスロットのアクティブな状態を判断できません。代わりに、一致しないスロットに対して
default.js
ファイルをレンダリングするか、default.js
が存在しない場合は404
をレンダリングします。
補足:
- 一致しないルートの
404
は、意図していないページで並列ルートを誤って描画しないようにするのに役立ちます。
default.js
初期ロードまたは完全なページリロード時に、一致しないスロットのフォールバックとしてレンダリングするdefault.js
ファイルを定義できます。
次のフォルダ構造を考えてみましょう。@team
スロットには/settings
ページがありますが、@analytics
にはありません。
/settings
に移動すると、@team
スロットは/settings
ページをレンダリングし、@analytics
スロットの現在アクティブなページを維持します。
更新時に、Next.jsは@analytics
のdefault.js
をレンダリングします。default.js
が存在しない場合は、404
がレンダリングされます。
さらに、children
は暗黙のスロットであるため、Next.jsが親ページのアクティブな状態を復元できない場合のフォールバックとしてdefault.js
ファイルを作成する必要があります。
useSelectedLayoutSegment(s)
useSelectedLayoutSegment
とuseSelectedLayoutSegments
の両方がparallelRoutesKey
パラメーターを受け取り、スロット内のアクティブなルートセグメントを読み取ることができます。
ユーザーがapp/@auth/login
(またはURLバーの/login
)に移動すると、loginSegment
は文字列"login"
と等しくなります。
例
条件付きルート
並列ルートを使用して、ユーザーロールなどの特定の条件に基づいてルートを条件付きでレンダリングできます。例えば、/admin
または/user
ロールに対して異なるダッシュボードページをレンダリングする:
タブグループ
スロット内にlayout
を追加して、ユーザーがスロットを独立してナビゲートできるようにします。これはタブの作成に便利です。
例えば、@analytics
スロットには/page-views
と/visitors
の2つのサブページがあります。
@analytics
内で、2つのページ間でタブを共有するためにlayout
ファイルを作成します:
モーダル
並列ルートはインターセプティングルートと組み合わせて、ディープリンクをサポートするモーダルを作成できます。これにより、モーダルを構築する際の一般的な課題を解決できます:
- モーダルコンテンツをURLを通じて共有可能にする。
- ページがリフレッシュされたときに、モーダルを閉じるのではなく、コンテキストを保持する。
- 前のルートに戻るのではなく、戻る操作でモーダルを閉じる。
- 前に進む際にモーダルを再度開く。
クライアントサイドナビゲーションを使用してレイアウトからログインモーダルを開くか、別の/login
ページにアクセスできるUIパターンを考えてみましょう:
このパターンを実装するには、まずメインのログインページをレンダリングする/login
ルートを作成します。
次に、@auth
スロット内にdefault.js
ファイルを追加し、null
を返します。これにより、アクティブでない場合にモーダルがレンダリングされないことを保証します。
@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
スロットでキャッチオールルートを使用してモーダルを閉じます。スロットに一致しなくなったルートへのクライアントサイドナビゲーションは引き続き表示されるため、モーダルを閉じるためにnull
を返すルートに一致させる必要があります。- 他の例としては、ギャラリー内の写真モーダルと専用の
/photo/[id]
ページを開くこと、サイドモーダルでショッピングカートを開くことなどがあります。- 遮断とパラレルルートを使用したモーダルの例を参照してください。
ローディングとエラーUI
パラレルルートは独立してストリーミングできるため、各ルートに独立したエラーとローディング状態を定義できます: