Parallele Routen

Paralleles Routing ermöglicht es Ihnen, eine oder mehrere Seiten gleichzeitig oder bedingt im selben Layout zu rendern. Für hochdynamische Bereiche einer Anwendung, wie Dashboards und Feeds in sozialen Netzwerken, kann paralleles Routing verwendet werden, um komplexe Routing-Muster zu implementieren.

Beispielsweise können Sie die Team- und Analytics-Seiten gleichzeitig rendern.

Diagramm für parallele Routen

Paralleles Routing ermöglicht es Ihnen, unabhängige Fehler- und Ladezustände für jede Route zu definieren, während sie unabhängig voneinander gestreamt werden.

Parallele Routen ermöglichen benutzerdefinierte Fehler- und Ladezustände

Paralleles Routing ermöglicht es Ihnen auch, einen Slot basierend auf bestimmten Bedingungen, wie dem Authentifizierungsstatus, bedingt zu rendern. Dies ermöglicht vollständig getrennten Code unter derselben URL.

Diagramm für bedingte Routen

Konvention

Parallele Routen werden mit benannten Slots erstellt. Slots werden mit der @folder-Konvention definiert und als Props an das Layout auf derselben Ebene übergeben.

Slots sind keine Routensegmente und beeinflussen nicht die URL-Struktur. Der Dateipfad /@team/members wäre unter /members erreichbar.

Beispielsweise definiert die folgende Dateistruktur zwei explizite Slots: @analytics und @team.

Dateisystemstruktur für parallele Routen

Die obige Ordnerstruktur bedeutet, dass die Komponente in app/layout.js nun die Slot-Props @analytics und @team akzeptiert und sie parallel zum children-Prop rendern kann:

export default function Layout(props: {
  children: React.ReactNode
  analytics: React.ReactNode
  team: React.ReactNode
}) {
  return (
    <>
      {props.children}
      {props.team}
      {props.analytics}
    </>
  )
}
export default function Layout(props) {
  return (
    <>
      {props.children}
      {props.team}
      {props.analytics}
    </>
  )
}

Gut zu wissen: Der children-Prop ist ein impliziter Slot, der keinem Ordner zugeordnet werden muss. Das bedeutet, app/page.js entspricht app/@children/page.js.

Nicht übereinstimmende Routen

Standardmäßig wird der Inhalt innerhalb eines Slots der aktuellen URL entsprechen.

Im Fall eines nicht übereinstimmenden Slots unterscheidet sich der von Next.js gerenderte Inhalt basierend auf der Routing-Technik und der Ordnerstruktur.

default.js

Sie können eine default.js-Datei definieren, die als Fallback gerendert wird, wenn Next.js den aktiven Zustand eines Slots basierend auf der aktuellen URL nicht wiederherstellen kann.

Betrachten Sie die folgende Ordnerstruktur. Der @team-Slot hat ein settings-Verzeichnis, @analytics jedoch nicht.

Nicht übereinstimmende Routen bei parallelen Routen

Bei der Navigation wird Next.js den zuvor aktiven Zustand des Slots rendern, auch wenn er nicht mit der aktuellen URL übereinstimmt.

Neuladen

Beim Neuladen wird Next.js zuerst versuchen, die default.js-Datei des nicht übereinstimmenden Slots zu rendern. Wenn diese nicht verfügbar ist, wird ein 404-Fehler gerendert.

Der 404-Fehler für nicht übereinstimmende Routen hilft sicherzustellen, dass Sie nicht versehentlich eine Route rendern, die nicht parallel gerendert werden sollte.

useSelectedLayoutSegment(s)

Sowohl useSelectedLayoutSegment als auch useSelectedLayoutSegments akzeptieren einen parallelRoutesKey, der es Ihnen ermöglicht, das aktive Routensegment innerhalb dieses Slots zu lesen.

'use client'

import { useSelectedLayoutSegment } from 'next/navigation'

export default async function Layout(props: {
  //...
  auth: React.ReactNode
}) {
  const loginSegments = useSelectedLayoutSegment('auth')
  // ...
}
'use client'

import { useSelectedLayoutSegment } from 'next/navigation'

export default async function Layout(props) {
  const loginSegments = useSelectedLayoutSegment('auth')
  // ...
}

Wenn ein Benutzer zu @auth/login navigiert oder /login in der URL-Leiste eingibt, wird loginSegments gleich dem String "login" sein.

Beispiele

Modale

Paralleles Routing kann verwendet werden, um Modale zu rendern.

Diagramm für parallele Routen

Der @auth-Slot rendert eine <Modal>-Komponente, die durch Navigation zu einer passenden Route, z.B. /login, angezeigt werden kann.

export default async function Layout(props: {
  // ...
  auth: React.ReactNode
}) {
  return (
    <>
      {/* ... */}
      {props.auth}
    </>
  )
}
export default async function Layout(props) {
  return (
    <>
      {/* ... */}
      {props.auth}
    </>
  )
}
import { Modal } from 'components/modal'

export default function Login() {
  return (
    <Modal>
      <h1>Login</h1>
      {/* ... */}
    </Modal>
  )
}
import { Modal } from 'components/modal'

export default function Login() {
  return (
    <Modal>
      <h1>Login</h1>
      {/* ... */}
    </Modal>
  )
}

Um sicherzustellen, dass der Inhalt des Modals nicht gerendert wird, wenn es nicht aktiv ist, können Sie eine default.js-Datei erstellen, die null zurückgibt.

export default function Default() {
  return null
}
export default function Default() {
  return null
}

Schließen eines Modals

Wenn ein Modal durch Client-Navigation initiiert wurde, z.B. durch <Link href="/login">, können Sie das Modal schließen, indem Sie router.back() aufrufen oder eine Link-Komponente verwenden.

'use client'
import { useRouter } from 'next/navigation'
import { Modal } from 'components/modal'

export default async function Login() {
  const router = useRouter()
  return (
    <Modal>
      <span onClick={() => router.back()}>Modal schließen</span>
      <h1>Login</h1>
      ...
    </Modal>
  )
}
'use client'
import { useRouter } from 'next/navigation'
import { Modal } from 'components/modal'

export default async function Login() {
  const router = useRouter()
  return (
    <Modal>
      <span onClick={() => router.back()}>Modal schließen</span>
      <h1>Login</h1>
      ...
    </Modal>
  )
}

Weitere Informationen zu Modalen finden Sie im Abschnitt Intercepting Routes.

Wenn Sie zu einem anderen Ort navigieren und ein Modal schließen möchten, können Sie auch eine Catch-all-Route verwenden.

Diagramm für parallele Routen
export default function CatchAll() {
  return null
}
export default function CatchAll() {
  return null
}

Catch-all-Routen haben Vorrang vor default.js.

Bedingte Routen

Paralleles Routing kann verwendet werden, um bedingtes Routing zu implementieren. Beispielsweise können Sie eine @dashboard- oder @login-Route basierend auf dem Authentifizierungsstatus rendern.

import { getUser } from '@/lib/auth'

export default function Layout({
  dashboard,
  login,
}: {
  dashboard: React.ReactNode
  login: React.ReactNode
}) {
  const isLoggedIn = getUser()
  return isLoggedIn ? dashboard : login
}
import { getUser } from '@/lib/auth'

export default function Layout({ dashboard, login }) {
  const isLoggedIn = getUser()
  return isLoggedIn ? dashboard : login
}
Beispiel für Authentifizierung mit parallelen Routen