Menu

Verknüpfung und Navigation

Es gibt vier Möglichkeiten, zwischen Routen in Next.js zu navigieren:

Diese Seite erklärt, wie Sie jede dieser Optionen verwenden, und geht detaillierter darauf ein, wie Navigation funktioniert.

<Link> ist eine integrierte Komponente, die das HTML-<a>-Tag erweitert, um Prefetching und clientseitige Navigation zwischen Routen zu ermöglichen. Es ist der primäre und empfohlene Weg, um in Next.js zwischen Routen zu navigieren.

Sie können es importieren aus next/link und einen href-Prop an die Komponente übergeben:

app/page.tsx
TypeScript
import Link from 'next/link'
 
export default function Page() {
  return <Link href="/dashboard">Dashboard</Link>
}

Es gibt weitere optionale Props, die Sie an <Link> übergeben können. Weitere Informationen finden Sie in der API-Referenz.

useRouter()-Hook

Der useRouter-Hook ermöglicht es Ihnen, programmatisch Routen aus Client-Komponenten zu ändern.

app/page.js
'use client'
 
import { useRouter } from 'next/navigation'
 
export default function Page() {
  const router = useRouter()
 
  return (
    <button type="button" onClick={() => router.push('/dashboard')}>
      Dashboard
    </button>
  )
}

Eine vollständige Liste der useRouter-Methoden finden Sie in der API-Referenz.

Empfehlung: Verwenden Sie die <Link>-Komponente, um zwischen Routen zu navigieren, es sei denn, Sie haben eine spezifische Anforderung für die Verwendung von useRouter.

redirect-Funktion

Verwenden Sie für Server-Komponenten stattdessen die redirect-Funktion.

app/team/[id]/page.tsx
TypeScript
import { redirect } from 'next/navigation'
 
async function fetchTeam(id: string) {
  const res = await fetch('https://...')
  if (!res.ok) return undefined
  return res.json()
}
 
export default async function Profile({ params }: { params: { id: string } }) {
  const team = await fetchTeam(params.id)
  if (!team) {
    redirect('/login')
  }
 
  // ...
}

Hinweis:

  • redirect gibt standardmäßig einen 307 (Temporäre Weiterleitung) Statuscode zurück. Bei Verwendung in einer Server-Aktion wird ein 303 (Andere) zurückgegeben, der häufig zum Weiterleiten auf eine Erfolgsseite nach einer POST-Anfrage verwendet wird.
  • redirect wirft intern einen Fehler, daher sollte es außerhalb von try/catch-Blöcken aufgerufen werden.
  • redirect kann in Client-Komponenten während des Rendering-Prozesses aufgerufen werden, aber nicht in Ereignis-Handlern. Verwenden Sie stattdessen den useRouter-Hook.
  • redirect akzeptiert auch absolute URLs und kann zum Weiterleiten zu externen Links verwendet werden.
  • Wenn Sie vor dem Rendering-Prozess weiterleiten möchten, verwenden Sie next.config.js oder Middleware.

Weitere Informationen finden Sie in der redirect-API-Referenz.

Verwendung der nativen History-API

Next.js ermöglicht die Verwendung der nativen window.history.pushState- und window.history.replaceState-Methoden, um den Browser-Verlaufsstapel zu aktualisieren, ohne die Seite neu zu laden.

pushState- und replaceState-Aufrufe integrieren sich in den Next.js-Router und ermöglichen die Synchronisation mit usePathname und useSearchParams.

window.history.pushState

Verwenden Sie es, um einen neuen Eintrag zum Browser-Verlaufsstapel hinzuzufügen. Der Benutzer kann zum vorherigen Status zurücknavigieren. Beispiel zum Sortieren einer Produktliste:

'use client'
 
import { useSearchParams } from 'next/navigation'
 
export default function SortProducts() {
  const searchParams = useSearchParams()
 
  function updateSorting(sortOrder: string) {
    const params = new URLSearchParams(searchParams.toString())
    params.set('sort', sortOrder)
    window.history.pushState(null, '', `?${params.toString()}`)
  }
 
  return (
    <>
      <button onClick={() => updateSorting('asc')}>Aufsteigend sortieren</button>
      <button onClick={() => updateSorting('desc')}>Absteigend sortieren</button>
    </>
  )
}
'use client'
 
import { useSearchParams } from 'next/navigation'
 
export default function SortProducts() {
  const searchParams = useSearchParams()
 
  function updateSorting(sortOrder) {
    const params = new URLSearchParams(searchParams.toString())
    params.set('sort', sortOrder)
    window.history.pushState(null, '', `?${params.toString()}`)
  }
 
  return (
    <>
      <button onClick={() => updateSorting('asc')}>Aufsteigend sortieren</button>
      <button onClick={() => updateSorting('desc')}>Absteigend sortieren</button>
    </>
  )
}

window.history.replaceState

Verwenden Sie es, um den aktuellen Eintrag im Browser-Verlaufsstapel zu ersetzen. Der Benutzer kann nicht zum vorherigen Status zurücknavigieren. Beispiel zum Wechseln der Anwendungssprache:

'use client'
 
import { usePathname } from 'next/navigation'
 
export function LocaleSwitcher() {
  const pathname = usePathname()
 
  function switchLocale(locale: string) {
    // z.B. '/en/about' oder '/fr/contact'
    const newPath = `/${locale}${pathname}`
    window.history.replaceState(null, '', newPath)
  }
 
  return (
    <>
      <button onClick={() => switchLocale('en')}>Englisch</button>
      <button onClick={() => switchLocale('fr')}>Französisch</button>
    </>
  )
}
'use client'
 
import { usePathname } from 'next/navigation'
 
export function LocaleSwitcher() {
  const pathname = usePathname()
 
  function switchLocale(locale) {
    // z.B. '/en/about' oder '/fr/contact'
    const newPath = `/${locale}${pathname}`
    window.history.replaceState(null, '', newPath)
  }
 
  return (
    <>
      <button onClick={() => switchLocale('en')}>Englisch</button>
      <button onClick={() => switchLocale('fr')}>Französisch</button>
    </>
  )
}

Wie Routing und Navigation funktionieren

Der App Router verwendet einen Hybridansatz für Routing und Navigation. Auf dem Server wird Ihr Anwendungscode automatisch Code-Split nach Routensegmenten. Und auf dem Client prefetcht und cached Next.js die Routensegmente. Das bedeutet, wenn ein Benutzer zu einer neuen Route navigiert, lädt der Browser die Seite nicht neu, und nur die sich ändernden Routensegmente werden neu gerendert - was die Navigations-Erfahrung und -Leistung verbessert.

1. Code-Splitting

Code Splitting ermöglicht es, den Anwendungscode in kleinere Bundles zu unterteilen, die vom Browser heruntergeladen und ausgeführt werden können. Dies reduziert die Menge der übertragenen Daten und die Ausführungszeit für jede Anfrage, was zu einer verbesserten Leistung führt.

Server-Komponenten ermöglichen eine automatische Code-Aufteilung durch Routensegmente. Das bedeutet, dass nur der Code geladen wird, der für die aktuelle Route benötigt wird.

2. Prefetching

Prefetching ist eine Methode, um eine Route im Hintergrund vorab zu laden, bevor der Benutzer sie besucht.

In Next.js gibt es zwei Arten des Prefetching:

  • <Link> Komponente: Routen werden automatisch prefetched, sobald sie im Viewport des Benutzers sichtbar werden. Das Prefetching erfolgt beim ersten Laden der Seite oder wenn sie durch Scrollen in den Sichtbereich kommt.
  • router.prefetch(): Der useRouter Hook kann verwendet werden, um Routen programmgesteuert zu prefetchen.

Das Standard-Prefetching-Verhalten der <Link> Komponente (wenn die prefetch Eigenschaft nicht angegeben oder auf null gesetzt ist) unterscheidet sich je nach Verwendung von loading.js. Nur das gemeinsame Layout bis hinunter zum ersten loading.js wird für 30s prefetched und zwischengespeichert. Dies reduziert die Kosten für das Abrufen einer gesamten dynamischen Route und bedeutet, dass Sie einen sofortigen Ladezustand für besseres visuelles Feedback anzeigen können.

Sie können Prefetching deaktivieren, indem Sie die prefetch Eigenschaft auf false setzen. Alternativ können Sie die vollständigen Seitendaten über die Ladegren zen hinaus prefetchen, indem Sie die prefetch Eigenschaft auf true setzen.

Weitere Informationen finden Sie in der <Link> API-Referenz.

Hinweis:

  • Prefetching ist nur in der Produktionsumgebung aktiviert, nicht in der Entwicklungsumgebung.

3. Caching

Next.js verfügt über einen In-Memory-Client-seitigen Cache namens Router-Cache. Während Benutzer durch die App navigieren, werden die React Server Component Payload von prefetched Routensegmenten und besuchten Routen im Cache gespeichert.

Das bedeutet, dass bei der Navigation der Cache so weit wie möglich wiederverwendet wird, anstatt eine neue Anfrage an den Server zu senden - was die Leistung verbessert, indem die Anzahl der Anfragen und übertragenen Daten reduziert wird.

Erfahren Sie mehr darüber, wie der Router-Cache funktioniert und wie er konfiguriert werden kann.

4. Partielles Rendering

Partielles Rendering bedeutet, dass bei der Navigation nur die sich ändernden Routensegmente auf dem Client neu gerendert werden, während gemeinsame Segmente beibehalten werden.

Zum Beispiel werden bei der Navigation zwischen zwei Sibling-Routen wie /dashboard/settings und /dashboard/analytics die settings-Seite ausgehängt, die analytics-Seite mit einem neuen Zustand eingehängt und das gemeinsame dashboard-Layout beibehalten. Dieses Verhalten besteht auch zwischen zwei Routen auf demselben dynamischen Segment, z.B. mit /blog/[slug]/page beim Wechsel von /blog/first zu /blog/second.

Funktionsweise des partiellen Renderings

Ohne partielles Rendering würde jede Navigation eine vollständige Seite auf dem Client neu rendern. Das Rendern nur des sich ändernden Segments reduziert die Menge der übertragenen Daten und die Ausführungszeit, was zu einer verbesserten Leistung führt.

5. Weiche Navigation

Browser führen eine "harte Navigation" beim Wechsel zwischen Seiten durch. Der Next.js App Router ermöglicht eine "weiche Navigation" zwischen Seiten, die sicherstellt, dass nur die sich ändernden Routensegmente neu gerendert werden (partielles Rendering). Dies ermöglicht die Beibehaltung des React-Client-Zustands während der Navigation.

6. Vor- und Zurück-Navigation

Standardmäßig behält Next.js die Scroll-Position bei Vor- und Zurück-Navigation bei und verwendet Routensegmente im Router-Cache erneut.

7. Routing zwischen pages/ und app/

Bei der schrittweisen Migration von pages/ zu app/ behandelt der Next.js-Router automatisch die harte Navigation zwischen den beiden. Um Übergänge von pages/ zu app/ zu erkennen, gibt es einen Client-Router-Filter, der probabilistische Überprüfung von App-Routen nutzt, was gelegentlich zu Fehlalarmen führen kann. Standardmäßig sollten solche Vorkommen sehr selten sein, da wir die Wahrscheinlichkeit für Fehlalarme auf 0,01% konfigurieren. Diese Wahrscheinlichkeit kann über die Option experimental.clientRouterFilterAllowedRate in next.config.js angepasst werden. Es ist wichtig zu beachten, dass die Senkung der Fehlalarm-Rate die Größe des generierten Filters im Client-Bundle erhöhen wird.

Alternativ können Sie die Behandlung komplett deaktivieren und das Routing zwischen pages/ und app/ manuell verwalten, indem Sie experimental.clientRouterFilter in next.config.js auf false setzen. Wenn dieses Feature deaktiviert ist, werden dynamische Routen in pages, die sich mit App-Routen überschneiden, standardmäßig nicht richtig navigiert.