Parallele Routen
Parallele Routen ermöglichen es Ihnen, eine oder mehrere Seiten gleichzeitig oder bedingt innerhalb desselben Layouts zu rendern. Sie sind nützlich für hochdynamische Bereiche einer Anwendung, wie Dashboards und Feeds in sozialen Netzwerken.
Beispielsweise können Sie bei einem Dashboard parallele Routen verwenden, um die Seiten team
und analytics
gleichzeitig zu rendern:

Slots
Parallele Routen werden mit benannten Slots erstellt. Slots werden mit der @folder
-Konvention definiert. Die folgende Dateistruktur definiert beispielsweise zwei Slots: @analytics
und @team
:

Slots werden als Props an das übergeordnete Layout übergeben. Für das obige Beispiel akzeptiert die Komponente in app/layout.js
nun die Slot-Props @analytics
und @team
und kann sie parallel zur children
-Prop rendern:
export default function Layout({
children,
team,
analytics,
}: {
children: React.ReactNode
analytics: React.ReactNode
team: React.ReactNode
}) {
return (
<>
{children}
{team}
{analytics}
</>
)
}
export default function Layout({ children, team, analytics }) {
return (
<>
{children}
{team}
{analytics}
</>
)
}
Slots sind jedoch keine Routen-Segmente und beeinflussen die URL-Struktur nicht. Für /@analytics/views
lautet die URL beispielsweise /views
, da @analytics
ein Slot ist.
Gut zu wissen:
- Die
children
-Prop ist ein impliziter Slot, der keinem Ordner zugeordnet werden muss. Das bedeutet,app/page.js
entsprichtapp/@children/page.js
.
Aktiver Zustand und Navigation
Standardmäßig verfolgt Next.js den aktiven Zustand (oder die Unterseite) für jeden Slot. Der Inhalt eines Slots hängt jedoch von der Art der Navigation ab:
- Soft Navigation: Bei clientseitiger Navigation führt Next.js ein partielles Rendering durch, ändert die Unterseite innerhalb des Slots und behält die aktiven Unterseiten der anderen Slots bei, auch wenn sie nicht zur aktuellen URL passen.
- Hard Navigation: Nach einem vollständigen Seitenladen (Browser-Aktualisierung) kann Next.js den aktiven Zustand für Slots, die nicht zur aktuellen URL passen, nicht bestimmen. Stattdessen wird eine
default.js
-Datei für nicht übereinstimmende Slots gerendert oder404
, wenndefault.js
nicht existiert.
Gut zu wissen:
- Die
404
für nicht übereinstimmende Routen stellt sicher, dass Sie nicht versehentlich eine parallele Route auf einer Seite rendern, für die sie nicht vorgesehen war.
default.js
Sie können eine default.js
-Datei definieren, die als Fallback für nicht übereinstimmende Slots während des initialen Ladens oder eines vollständigen Seiten-Neuladens dient.
Betrachten Sie die folgende Ordnerstruktur. Der @team
-Slot hat eine /settings
-Seite, @analytics
jedoch nicht.

Bei der Navigation zu /settings
rendert der @team
-Slot die /settings
-Seite, während die aktuell aktive Seite des @analytics
-Slots beibehalten wird.
Bei einer Aktualisierung rendert Next.js eine default.js
für @analytics
. Wenn default.js
nicht existiert, wird stattdessen ein 404
gerendert.
Da children
ein impliziter Slot ist, müssen Sie auch eine default.js
-Datei erstellen, um einen Fallback für children
zu rendern, wenn Next.js den aktiven Zustand der übergeordneten Seite nicht wiederherstellen kann.
useSelectedLayoutSegment(s)
Sowohl useSelectedLayoutSegment
als auch useSelectedLayoutSegments
akzeptieren einen parallelRoutesKey
-Parameter, mit dem Sie das aktive Routen-Segment innerhalb eines Slots auslesen können.
'use client'
import { useSelectedLayoutSegment } from 'next/navigation'
export default function Layout({ auth }: { auth: React.ReactNode }) {
const loginSegment = useSelectedLayoutSegment('auth')
// ...
}
'use client'
import { useSelectedLayoutSegment } from 'next/navigation'
export default function Layout({ auth }) {
const loginSegment = useSelectedLayoutSegment('auth')
// ...
}
Wenn ein Benutzer zu app/@auth/login
(oder /login
in der URL-Leiste) navigiert, ist loginSegment
gleich dem String "login"
.
Beispiele
Bedingte Routen
Sie können parallele Routen verwenden, um Routen basierend auf bestimmten Bedingungen, wie Benutzerrollen, bedingt zu rendern. Beispielsweise, um eine unterschiedliche Dashboard-Seite für die Rollen /admin
oder /user
zu rendern:

import { checkUserRole } from '@/lib/auth'
export default function Layout({
user,
admin,
}: {
user: React.ReactNode
admin: React.ReactNode
}) {
const role = checkUserRole()
return <>{role === 'admin' ? admin : user}</>
}
import { checkUserRole } from '@/lib/auth'
export default function Layout({ user, admin }) {
const role = checkUserRole()
return <>{role === 'admin' ? admin : user}</>
}
Tab-Gruppen
Sie können innerhalb eines Slots ein layout
hinzufügen, um Benutzern eine unabhängige Navigation des Slots zu ermöglichen. Dies ist nützlich für die Erstellung von Tabs.
Beispielsweise hat der @analytics
-Slot zwei Unterseiten: /page-views
und /visitors
.

Erstellen Sie innerhalb von @analytics
eine layout
-Datei, um die Tabs zwischen den beiden Seiten zu teilen:
import Link from 'next/link'
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<>
<nav>
<Link href="/page-views">Page Views</Link>
<Link href="/visitors">Visitors</Link>
</nav>
<div>{children}</div>
</>
)
}
import Link from 'next/link'
export default function Layout({ children }) {
return (
<>
<nav>
<Link href="/page-views">Page Views</Link>
<Link href="/visitors">Visitors</Link>
</nav>
<div>{children}</div>
</>
)
}
Modale
Parallele Routen können zusammen mit Intercepting Routes verwendet werden, um modale Fenster zu erstellen. Dies ermöglicht es Ihnen, häufige Herausforderungen beim Erstellen von modalen Fenstern zu lösen, wie:
- Teilbarkeit des modalen Inhalts über eine URL.
- Erhalt des Kontexts bei einer Seitenaktualisierung, anstatt das modale Fenster zu schließen.
- Schließen des modalen Fensters bei Rückwärtsnavigation, anstatt zur vorherigen Route zu gehen.
- Wiederöffnen des modalen Fensters bei Vorwärtsnavigation.
Betrachten Sie das folgende UI-Muster, bei dem ein Benutzer ein Login-Modalfenster aus einem Layout über clientseitige Navigation öffnen oder eine separate /login
-Seite aufrufen kann:

Um dieses Muster zu implementieren, erstellen Sie zunächst eine /login
-Route, die Ihre Haupt-Login-Seite rendert.

import { Login } from '@/app/ui/login'
export default function Page() {
return <Login />
}
import { Login } from '@/app/ui/login'
export default function Page() {
return <Login />
}
Fügen Sie dann im @auth
-Slot eine default.js
-Datei hinzu, die null
zurückgibt. Dadurch wird sichergestellt, dass das modale Fenster nicht gerendert wird, wenn es nicht aktiv ist.
export default function Default() {
return null
}
export default function Default() {
return null
}
Interceptieren Sie im @auth
-Slot die /login
-Route, indem Sie den /(.)login
-Ordner aktualisieren. Importieren Sie die <Modal>
-Komponente und ihre Kinder in die /(.)login/page.tsx
-Datei:
import { Modal } from '@/app/ui/modal'
import { Login } from '@/app/ui/login'
export default function Page() {
return (
<Modal>
<Login />
</Modal>
)
}
import { Modal } from '@/app/ui/modal'
import { Login } from '@/app/ui/login'
export default function Page() {
return (
<Modal>
<Login />
</Modal>
)
}
Gut zu wissen:
- Die Konvention zum Intercepten der Route, z.B.
(.)
, hängt von Ihrer Dateisystemstruktur ab. Siehe Intercepting Routes Konvention.- Durch die Trennung der
<Modal>
-Funktionalität vom modalen Inhalt (<Login>
) können Sie sicherstellen, dass jeglicher Inhalt innerhalb des modalen Fensters, z.B. Formulare, Server-Komponenten sind. Siehe Interleaving Client and Server Components für weitere Informationen.
Öffnen des modalen Fensters
Nun können Sie den Next.js-Router nutzen, um das modale Fenster zu öffnen und zu schließen. Dadurch wird sichergestellt, dass die URL korrekt aktualisiert wird, wenn das modale Fenster geöffnet ist, und bei Vorwärts- und Rückwärtsnavigation.
Um das modale Fenster zu öffnen, übergeben Sie den @auth
-Slot als Prop an das übergeordnete Layout und rendern ihn zusammen mit der children
-Prop.
import Link from 'next/link'
export default function Layout({
auth,
children,
}: {
auth: React.ReactNode
children: React.ReactNode
}) {
return (
<>
<nav>
<Link href="/login">Open modal</Link>
</nav>
<div>{auth}</div>
<div>{children}</div>
</>
)
}
import Link from 'next/link'
export default function Layout({ auth, children }) {
return (
<>
<nav>
<Link href="/login">Open modal</Link>
</nav>
<div>{auth}</div>
<div>{children}</div>
</>
)
}
Wenn der Benutzer auf den <Link>
klickt, öffnet sich das modale Fenster, anstatt zur /login
-Seite zu navigieren. Bei einer Aktualisierung oder initialem Laden führt die Navigation zu /login
jedoch zur Haupt-Login-Seite.
Schließen des modalen Fensters
Sie können das modale Fenster schließen, indem Sie router.back()
aufrufen oder die Link
-Komponente verwenden.
'use client'
import { useRouter } from 'next/navigation'
export function Modal({ children }: { children: React.ReactNode }) {
const router = useRouter()
return (
<>
<button
onClick={() => {
router.back()
}}
>
Close modal
</button>
<div>{children}</div>
</>
)
}
'use client'
import { useRouter } from 'next/navigation'
export function Modal({ children }) {
const router = useRouter()
return (
<>
<button
onClick={() => {
router.back()
}}
>
Close modal
</button>
<div>{children}</div>
</>
)
}
Wenn Sie die Link
-Komponente verwenden, um von einer Seite wegzunavigieren, die den @auth
-Slot nicht mehr rendern soll, verwenden wir eine Catch-all-Route, die null
zurückgibt.
import Link from 'next/link'
export function Modal({ children }: { children: React.ReactNode }) {
return (
<>
<Link href="/">Close modal</Link>
<div>{children}</div>
</>
)
}
import Link from 'next/link'
export function Modal({ children }) {
return (
<>
<Link href="/">Close modal</Link>
<div>{children}</div>
</>
)
}
export default function CatchAll() {
return null
}
export default function CatchAll() {
return null
}
Gut zu wissen:
- Wir verwenden eine Catch-all-Route in unserem
@auth
-Slot, um das modale Fenster aufgrund des in Aktiver Zustand und Navigation beschriebenen Verhaltens zu schließen. Da clientseitige Navigationen zu einer Route, die nicht mehr zum Slot passt, sichtbar bleiben, müssen wir den Slot mit einer Route abgleichen, dienull
zurückgibt, um das modale Fenster zu schließen.- Weitere Beispiele könnten das Öffnen eines Foto-Modalfensters in einer Galerie sein, während es auch eine dedizierte
/photo/[id]
-Seite gibt, oder das Öffnen eines Warenkorbs in einem seitlichen modalen Fenster.- Sehen Sie sich ein Beispiel für modale Fenster mit Intercepted und Parallel Routes an.
Lade- und Fehler-UI
Parallele Routen können unabhängig voneinander gestreamt werden, sodass Sie unabhängige Fehler- und Ladezustände für jede Route definieren können:

Weitere Informationen finden Sie in der Dokumentation zu Lade-UI und Fehlerbehandlung.
Dynamische Routen
Dynamische Routen können verwendet werden, um Routensegmente programmatisch aus dynamischen Daten zu generieren.
Intercepting Routes (Abfangende Routen)
Verwenden Sie abfangende Routen, um eine neue Route innerhalb des aktuellen Layouts zu laden und dabei die Browser-URL zu maskieren, nützlich für erweiterte Routing-Muster wie Modals.