Migration vom Pages- zum App-Router
Diese Anleitung hilft Ihnen dabei:
- Ihre Next.js-Anwendung von Version 12 auf Version 13 zu aktualisieren
- Funktionen zu aktualisieren, die sowohl im
pages
- als auch imapp
-Verzeichnis funktionieren - Ihre bestehende Anwendung schrittweise von
pages
aufapp
zu migrieren
Aktualisierung
Node.js-Version
Die mindestens erforderliche Node.js-Version ist nun v18.17. Weitere Informationen finden Sie in der Node.js-Dokumentation.
Next.js-Version
Um auf Next.js Version 13 zu aktualisieren, führen Sie den folgenden Befehl mit Ihrem bevorzugten Paketmanager aus:
ESLint-Version
Falls Sie ESLint verwenden, müssen Sie Ihre ESLint-Version aktualisieren:
Gut zu wissen: Möglicherweise müssen Sie den ESLint-Server in VS Code neu starten, damit die ESLint-Änderungen wirksam werden. Öffnen Sie die Befehlspalette (
cmd+shift+p
auf Mac;ctrl+shift+p
auf Windows) und suchen Sie nachESLint: Restart ESLint Server
.
Nächste Schritte
Nach der Aktualisierung finden Sie in den folgenden Abschnitten die nächsten Schritte:
- Neue Funktionen aktualisieren: Eine Anleitung, die Ihnen hilft, neue Funktionen wie die verbesserten Image- und Link-Komponenten zu nutzen.
- Migration vom
pages
- zumapp
-Verzeichnis: Eine Schritt-für-Schritt-Anleitung, die Ihnen bei der schrittweisen Migration vompages
- zumapp
-Verzeichnis hilft.
Neue Funktionen aktualisieren
Next.js 13 führte den neuen App-Router mit neuen Funktionen und Konventionen ein. Der neue Router ist im app
-Verzeichnis verfügbar und koexistiert mit dem pages
-Verzeichnis.
Die Aktualisierung auf Next.js 13 erfordert nicht die Verwendung des App-Routers. Sie können weiterhin pages
mit neuen Funktionen verwenden, die in beiden Verzeichnissen funktionieren, wie die aktualisierte Image-Komponente, Link-Komponente, Script-Komponente und Schriftoptimierung.
<Image/>
-Komponente
Next.js 12 führte Verbesserungen an der Image-Komponente mit einem temporären Import ein: next/future/image
. Diese Verbesserungen umfassten weniger clientseitiges JavaScript, einfachere Möglichkeiten zur Erweiterung und Gestaltung von Bildern, bessere Barrierefreiheit und natives Browser-Lazy-Loading.
In Version 13 ist dieses neue Verhalten nun standardmäßig in next/image
enthalten.
Es gibt zwei Codemods, die Ihnen bei der Migration zur neuen Image-Komponente helfen:
next-image-to-legacy-image
-Codemod: Benenntnext/image
-Importe sicher und automatisch innext/legacy/image
um. Bestehende Komponenten behalten das gleiche Verhalten bei.next-image-experimental
-Codemod: Fügt gefährlich Inline-Styles hinzu und entfernt ungenutzte Props. Dies ändert das Verhalten bestehender Komponenten, um den neuen Standard zu entsprechen. Um diesen Codemod zu verwenden, müssen Sie zuerst dennext-image-to-legacy-image
-Codemod ausführen.
<Link>
-Komponente
Die <Link>
-Komponente erfordert nicht mehr das manuelle Hinzufügen eines <a>
-Tags als Kind. Dieses Verhalten wurde als experimentelle Option in Version 12.2 hinzugefügt und ist nun der Standard. In Next.js 13 rendert <Link>
immer <a>
und ermöglicht es Ihnen, Props an das zugrunde liegende Tag weiterzugeben.
Beispiel:
Um Ihre Links auf Next.js 13 zu aktualisieren, können Sie den new-link
-Codemod verwenden.
<Script>
-Komponente
Das Verhalten von next/script
wurde aktualisiert, um sowohl pages
als auch app
zu unterstützen, aber einige Änderungen sind erforderlich, um eine reibungslose Migration zu gewährleisten:
- Verschieben Sie alle
beforeInteractive
-Scripts, die Sie zuvor in_document.js
eingebunden haben, in die Root-Layout-Datei (app/layout.tsx
). - Die experimentelle
worker
-Strategie funktioniert noch nicht inapp
, und Scripts mit dieser Strategie müssen entweder entfernt oder geändert werden, um eine andere Strategie zu verwenden (z.B.lazyOnload
). onLoad
,onReady
undonError
-Handler funktionieren nicht in Server-Komponenten, daher sollten Sie sie in eine Client-Komponente verschieben oder ganz entfernen.
Schriftoptimierung
Bisher half Next.js Ihnen, Schriften zu optimieren, indem Schrift-CSS inline eingebunden wurde. Version 13 führt das neue next/font
-Modul ein, das Ihnen die Möglichkeit gibt, Ihre Schriftladeerfahrung anzupassen und gleichzeitig eine hervorragende Leistung und Privatsphäre zu gewährleisten. next/font
wird sowohl im pages
- als auch im app
-Verzeichnis unterstützt.
Während Inline-CSS in pages
weiterhin funktioniert, funktioniert es nicht in app
. Sie sollten stattdessen next/font
verwenden.
Weitere Informationen zur Verwendung von next/font
finden Sie auf der Seite Schriftoptimierung.
Migration von pages
zu app
🎥 Ansehen: Erfahren Sie, wie Sie den App-Router schrittweise einführen können → YouTube (16 Minuten).
Der Wechsel zum App-Router könnte das erste Mal sein, dass Sie React-Funktionen verwenden, auf denen Next.js aufbaut, wie Server-Komponenten, Suspense und mehr. In Kombination mit neuen Next.js-Funktionen wie Spezialdateien und Layouts bedeutet die Migration neue Konzepte, mentale Modelle und Verhaltensänderungen, die es zu lernen gilt.
Wir empfehlen, die kombinierte Komplexität dieser Aktualisierungen zu reduzieren, indem Sie Ihre Migration in kleinere Schritte unterteilen. Das app
-Verzeichnis ist absichtlich so gestaltet, dass es gleichzeitig mit dem pages
-Verzeichnis funktioniert, um eine schrittweise Migration Seite für Seite zu ermöglichen.
- Das
app
-Verzeichnis unterstützt verschachtelte Routen und Layouts. Mehr erfahren. - Verwenden Sie verschachtelte Ordner, um Routen zu definieren, und eine spezielle
page.js
-Datei, um ein Routensegment öffentlich zugänglich zu machen. Mehr erfahren. - Spezialdateikonventionen werden verwendet, um die Benutzeroberfläche für jedes Routensegment zu erstellen. Die häufigsten Spezialdateien sind
page.js
undlayout.js
.- Verwenden Sie
page.js
, um eine benutzerdefinierte Benutzeroberfläche für eine Route zu definieren. - Verwenden Sie
layout.js
, um eine Benutzeroberfläche zu definieren, die über mehrere Routen hinweg geteilt wird. - Die Dateierweiterungen
.js
,.jsx
oder.tsx
können für Spezialdateien verwendet werden.
- Verwenden Sie
- Sie können andere Dateien wie Komponenten, Styles, Tests und mehr im
app
-Verzeichnis zusammenstellen. Mehr erfahren. - Datenabruffunktionen wie
getServerSideProps
undgetStaticProps
wurden durch eine neue API inapp
ersetzt.getStaticPaths
wurde durchgenerateStaticParams
ersetzt. pages/_app.js
undpages/_document.js
wurden durch ein einzelnesapp/layout.js
-Root-Layout ersetzt. Mehr erfahren.pages/_error.js
wurde durch granulareerror.js
-Spezialdateien ersetzt. Mehr erfahren.pages/404.js
wurde durch dienot-found.js
-Datei ersetzt.pages/api/*
-API-Routen wurden durch dieroute.js
-Spezialdatei (Route-Handler) ersetzt.
Schritt 1: Erstellen des app
-Verzeichnisses
Aktualisieren Sie auf die neueste Next.js-Version (erfordert 13.4 oder höher):
Erstellen Sie dann ein neues app
-Verzeichnis im Stammverzeichnis Ihres Projekts (oder im src/
-Verzeichnis).
Schritt 2: Erstellen eines Root-Layouts
Erstellen Sie eine neue app/layout.tsx
-Datei im app
-Verzeichnis. Dies ist ein Root-Layout, das für alle Routen in app
gilt.
- Das
app
-Verzeichnis muss ein Root-Layout enthalten. - Das Root-Layout muss
<html>
- und<body>
-Tags definieren, da Next.js diese nicht automatisch erstellt. - Das Root-Layout ersetzt die
pages/_app.tsx
- undpages/_document.tsx
-Dateien. - Die Dateierweiterungen
.js
,.jsx
oder.tsx
können für Layout-Dateien verwendet werden.
Um <head>
-HTML-Elemente zu verwalten, können Sie die integrierte SEO-Unterstützung verwenden:
Migration von _document.js
und _app.js
Falls Sie eine bestehende _app
- oder _document
-Datei haben, können Sie deren Inhalte (z.B. globale Styles) in das Root-Layout (app/layout.tsx
) kopieren. Styles in app/layout.tsx
gelten nicht für pages/*
. Sie sollten _app
/_document
während der Migration behalten, um zu verhindern, dass Ihre pages/*
-Routen brechen. Sobald die Migration abgeschlossen ist, können Sie sie sicher löschen.
Falls Sie React Context-Provider verwenden, müssen diese in eine Client-Komponente verschoben werden.
Migration des getLayout()
-Musters zu Layouts (Optional)
Next.js empfahl, eine Eigenschaft zu Page-Komponenten hinzuzufügen, um pro-Seite-Layouts im pages
-Verzeichnis zu erreichen. Dieses Muster kann durch die native Unterstützung für verschachtelte Layouts im app
-Verzeichnis ersetzt werden.
Vorher- und Nachher-Beispiel anzeigen
Vorher
Nachher
-
Entfernen Sie die
Page.getLayout
-Eigenschaft auspages/dashboard/index.js
und folgen Sie den Schritten zur Migration von Seiten in dasapp
-Verzeichnis.app/dashboard/page.js -
Verschieben Sie den Inhalt von
DashboardLayout
in eine neue Client-Komponente, um das Verhalten despages
-Verzeichnisses beizubehalten.app/dashboard/DashboardLayout.js -
Importieren Sie
DashboardLayout
in eine neuelayout.js
-Datei imapp
-Verzeichnis.app/dashboard/layout.js -
Sie können nicht-interaktive Teile von
DashboardLayout.js
(Client-Komponente) schrittweise inlayout.js
(Server-Komponente) verschieben, um die Menge an Komponenten-JavaScript zu reduzieren, die Sie an den Client senden.
Schritt 3: Migration von next/head
Im pages
-Verzeichnis wird die next/head
-React-Komponente verwendet, um <head>
-HTML-Elemente wie title
und meta
zu verwalten. Im app
-Verzeichnis wird next/head
durch die neue integrierte SEO-Unterstützung ersetzt.
Vorher:
Nachher:
Alle Metadatenoptionen anzeigen.
Schritt 4: Migration von Seiten
- Seiten im
app
-Verzeichnis sind standardmäßig Server Components (Server-Komponenten). Dies unterscheidet sich vompages
-Verzeichnis, wo Seiten Client Components (Client-Komponenten) sind. - Die Datenabfrage (Data Fetching) hat sich in
app
geändert.getServerSideProps
,getStaticProps
undgetInitialProps
wurden durch eine einfachere API ersetzt. - Das
app
-Verzeichnis verwendet verschachtelte Ordner, um Routen zu definieren, und eine speziellepage.js
-Datei, um ein Routensegment öffentlich zugänglich zu machen. -
pages
-Verzeichnisapp
-VerzeichnisRoute index.js
page.js
/
about.js
about/page.js
/about
blog/[slug].js
blog/[slug]/page.js
/blog/post-1
Wir empfehlen, die Migration einer Seite in zwei Hauptschritte aufzuteilen:
- Schritt 1: Verschieben der standardmäßig exportierten Page-Komponente in eine neue Client-Komponente.
- Schritt 2: Importieren der neuen Client-Komponente in eine neue
page.js
-Datei imapp
-Verzeichnis.
Gut zu wissen: Dies ist der einfachste Migrationspfad, da er das vergleichbarste Verhalten zum
pages
-Verzeichnis aufweist.
Schritt 1: Erstellen einer neuen Client-Komponente
- Erstellen Sie eine neue separate Datei im
app
-Verzeichnis (z.B.app/home-page.tsx
oder ähnlich), die eine Client-Komponente exportiert. Um Client-Komponenten zu definieren, fügen Sie die'use client'
-Direktive am Anfang der Datei ein (vor allen Imports).- Ähnlich wie beim Pages Router gibt es einen Optimierungsschritt, um Client-Komponenten beim ersten Seitenaufruf als statisches HTML vorzurrendern.
- Verschieben Sie die standardmäßig exportierte Page-Komponente von
pages/index.js
nachapp/home-page.tsx
.
Schritt 2: Erstellen einer neuen Seite
-
Erstellen Sie eine neue
app/page.tsx
-Datei imapp
-Verzeichnis. Dies ist standardmäßig eine Server-Komponente. -
Importieren Sie die
home-page.tsx
-Client-Komponente in die Seite. -
Falls Sie in
pages/index.js
Daten abgefragt haben, verschieben Sie die Datenabfragelogik direkt in die Server-Komponente unter Verwendung der neuen Datenabfrage-APIs. Weitere Details finden Sie im Leitfaden zur Datenabfrage-Migration. -
Falls Ihre vorherige Seite
useRouter
verwendet hat, müssen Sie auf die neuen Routing-Hooks umstellen. Mehr erfahren. -
Starten Sie Ihren Entwicklungsserver und rufen Sie
http://localhost:3000
auf. Sie sollten Ihre bestehende Index-Route sehen, die nun über dasapp
-Verzeichnis bereitgestellt wird.
Schritt 5: Migration von Routing-Hooks
Ein neuer Router wurde hinzugefügt, um das neue Verhalten im app
-Verzeichnis zu unterstützen.
In app
sollten Sie die drei neuen Hooks verwenden, die aus next/navigation
importiert werden: useRouter()
, usePathname()
und useSearchParams()
.
- Der neue
useRouter
-Hook wird ausnext/navigation
importiert und verhält sich anders als deruseRouter
-Hook inpages
, der ausnext/router
importiert wird.- Der
useRouter
-Hook ausnext/router
wird imapp
-Verzeichnis nicht unterstützt, kann aber weiterhin impages
-Verzeichnis verwendet werden.
- Der
- Der neue
useRouter
gibt nicht denpathname
-String zurück. Verwenden Sie stattdessen den separatenusePathname
-Hook. - Der neue
useRouter
gibt nicht dasquery
-Objekt zurück. Suchparameter und dynamische Routenparameter sind jetzt getrennt. Verwenden Sie stattdessen die HooksuseSearchParams
unduseParams
. - Sie können
useSearchParams
undusePathname
kombinieren, um auf Seitenänderungen zu reagieren. Weitere Details finden Sie im Abschnitt Router-Ereignisse (Router Events). - Diese neuen Hooks werden nur in Client-Komponenten unterstützt. Sie können nicht in Server-Komponenten verwendet werden.
Zusätzlich weist der neue useRouter
-Hook folgende Änderungen auf:
isFallback
wurde entfernt, dafallback
ersetzt wurde.- Die Werte
locale
,locales
,defaultLocales
,domainLocales
wurden entfernt, da die integrierten i18n-Funktionen von Next.js imapp
-Verzeichnis nicht mehr notwendig sind. Mehr über i18n erfahren. basePath
wurde entfernt. Die Alternative wird nicht Teil vonuseRouter
sein. Sie wurde noch nicht implementiert.asPath
wurde entfernt, da das Konzept vonas
aus dem neuen Router entfernt wurde.isReady
wurde entfernt, da es nicht mehr notwendig ist. Während des statischen Renderings (Static Rendering) wird jede Komponente, die denuseSearchParams()
-Hook verwendet, den Prerendering-Schritt überspringen und stattdessen zur Laufzeit auf dem Client gerendert.route
wurde entfernt.usePathname
oderuseSelectedLayoutSegments()
bieten eine Alternative.
Siehe die useRouter()
-API-Referenz.
Gemeinsame Nutzung von Komponenten zwischen pages
und app
Um Komponenten zwischen dem pages
- und app
-Router kompatibel zu halten, verweisen Sie auf den useRouter
-Hook aus next/compat/router
.
Dies ist der useRouter
-Hook aus dem pages
-Verzeichnis, der jedoch für die gemeinsame Nutzung von Komponenten zwischen den Routern gedacht ist. Sobald Sie bereit sind, ihn nur im app
-Router zu verwenden, aktualisieren Sie auf den neuen useRouter
aus next/navigation
.
Schritt 6: Migration von Datenabfrage-Methoden
Das pages
-Verzeichnis verwendet getServerSideProps
und getStaticProps
, um Daten für Seiten abzufragen. Im app
-Verzeichnis wurden diese bisherigen Datenabfragefunktionen durch eine einfachere API ersetzt, die auf fetch()
und asynchronen React Server Components basiert.
Serverseitiges Rendering (getServerSideProps
)
Im pages
-Verzeichnis wird getServerSideProps
verwendet, um Daten auf dem Server abzufragen und Props an die standardmäßig exportierte React-Komponente in der Datei weiterzuleiten. Das initiale HTML für die Seite wird vom Server vorgerendert, gefolgt vom "Hydrieren" der Seite im Browser (um sie interaktiv zu machen).
Im App Router können wir unsere Datenabfrage direkt in unseren React-Komponenten mit Server Components (Server-Komponenten) platzieren. Dies ermöglicht es uns, weniger JavaScript an den Client zu senden, während das gerenderte HTML vom Server beibehalten wird.
Durch Setzen der cache
-Option auf no-store
können wir angeben, dass die abgefragten Daten niemals zwischengespeichert werden sollen. Dies ist ähnlich wie getServerSideProps
im pages
-Verzeichnis.
Zugriff auf das Request-Objekt
Im pages
-Verzeichnis können Sie anforderungsbasierte Daten basierend auf der Node.js HTTP-API abrufen.
Beispielsweise können Sie das req
-Objekt aus getServerSideProps
abrufen und damit die Cookies und Header der Anfrage auslesen.
Das app
-Verzeichnis stellt neue schreibgeschützte Funktionen zum Abrufen von Anfragedaten bereit:
headers
: Basierend auf der Web Headers API und kann in Server Components (Server-Komponenten) verwendet werden, um Anfrage-Header abzurufen.cookies
: Basierend auf der Web Cookies API und kann in Server Components (Server-Komponenten) verwendet werden, um Cookies abzurufen.
Statische Seitengenerierung (getStaticProps
)
Im pages
-Verzeichnis wird die Funktion getStaticProps
verwendet, um eine Seite zur Build-Zeit vorzurrendern. Diese Funktion kann verwendet werden, um Daten von einer externen API oder direkt aus einer Datenbank abzufragen und diese Daten während des Builds an die gesamte Seite weiterzuleiten.
Im app
-Verzeichnis wird die Datenabfrage mit fetch()
standardmäßig auf cache: 'force-cache'
gesetzt, was die Anfragedaten bis zur manuellen Ungültigmachung zwischenspeichert. Dies ist ähnlich wie getStaticProps
im pages
-Verzeichnis.
Dynamische Pfade (getStaticPaths
)
Im pages
-Verzeichnis wird die Funktion getStaticPaths
verwendet, um die dynamischen Pfade zu definieren, die zur Build-Zeit vorgerendert werden sollen.
Im app
-Verzeichnis wird getStaticPaths
durch generateStaticParams
ersetzt.
generateStaticParams
verhält sich ähnlich wie getStaticPaths
, bietet jedoch eine vereinfachte API für die Rückgabe von Routenparametern und kann innerhalb von Layouts verwendet werden. Die Rückgabeform von generateStaticParams
ist ein Array von Segmenten anstelle eines Arrays verschachtelter param
-Objekte oder eines Strings mit aufgelösten Pfaden.
Der Name generateStaticParams
ist für das neue Modell im app
-Verzeichnis passender als getStaticPaths
. Das Präfix get
wird durch das beschreibendere generate
ersetzt, das besser allein steht, da getStaticProps
und getServerSideProps
nicht mehr notwendig sind. Das Suffix Paths
wird durch Params
ersetzt, das besser für verschachteltes Routing mit mehreren dynamischen Segmenten geeignet ist.
Ersetzen von fallback
Im pages
-Verzeichnis wird die Eigenschaft fallback
, die von getStaticPaths
zurückgegeben wird, verwendet, um das Verhalten einer Seite zu definieren, die nicht zur Build-Zeit vorgerendert wurde. Diese Eigenschaft kann auf true
gesetzt werden, um eine Fallback-Seite anzuzeigen, während die Seite generiert wird, auf false
, um eine 404-Seite anzuzeigen, oder auf 'blocking'
, um die Seite zur Laufzeit zu generieren.
Im app
-Verzeichnis steuert die Eigenschaft config.dynamicParams
, wie mit Parametern umgegangen wird, die nicht in generateStaticParams
enthalten sind:
true
: (Standard) Dynamische Segmente, die nicht ingenerateStaticParams
enthalten sind, werden bei Bedarf generiert.false
: Dynamische Segmente, die nicht ingenerateStaticParams
enthalten sind, geben einen 404-Fehler zurück.
Dies ersetzt die Option fallback: true | false | 'blocking'
von getStaticPaths
im pages
-Verzeichnis. Die Option fallback: 'blocking'
ist in dynamicParams
nicht enthalten, da der Unterschied zwischen 'blocking'
und true
mit Streaming vernachlässigbar ist.
Wenn dynamicParams
auf true
(Standard) gesetzt ist, wird ein angefordertes Routensegment, das noch nicht generiert wurde, serverseitig gerendert und zwischengespeichert.
Incremental Static Regeneration (getStaticProps
mit revalidate
)
Im pages
-Verzeichnis ermöglicht die Funktion getStaticProps
das Hinzufügen eines revalidate
-Felds, um eine Seite nach einer bestimmten Zeit automatisch neu zu generieren.
Im app
-Verzeichnis kann das Abrufen von Daten mit fetch()
revalidate
verwenden, wodurch die Anfrage für die angegebene Anzahl von Sekunden zwischengespeichert wird.
API-Routen
API-Routen funktionieren weiterhin im pages/api
-Verzeichnis ohne Änderungen. Sie wurden jedoch im app
-Verzeichnis durch Route Handler ersetzt.
Route Handler ermöglichen es Ihnen, benutzerdefinierte Anfragehandler für eine bestimmte Route mit den Web-Request- und Response-APIs zu erstellen.
Gut zu wissen: Wenn Sie zuvor API-Routen verwendet haben, um eine externe API vom Client aus aufzurufen, können Sie jetzt stattdessen Server Components verwenden, um Daten sicher abzurufen. Erfahren Sie mehr über Datenabruf.
Single-Page Applications
Wenn Sie gleichzeitig von einer Single-Page Application (SPA) zu Next.js migrieren, lesen Sie unsere Dokumentation, um mehr zu erfahren.
Schritt 7: Styling
Im pages
-Verzeichnis sind globale Stylesheets auf pages/_app.js
beschränkt. Mit dem app
-Verzeichnis wurde diese Einschränkung aufgehoben. Globale Styles können zu jedem Layout, jeder Seite oder jeder Komponente hinzugefügt werden.
Tailwind CSS
Wenn Sie Tailwind CSS verwenden, müssen Sie das app
-Verzeichnis zu Ihrer tailwind.config.js
-Datei hinzufügen:
Sie müssen auch Ihre globalen Styles in Ihrer app/layout.js
-Datei importieren:
Erfahren Sie mehr über Styling mit Tailwind CSS
Verwendung von App Router zusammen mit Pages Router
Beim Navigieren zwischen Routen, die von den verschiedenen Next.js-Routern bereitgestellt werden, erfolgt eine Hard Navigation. Die automatische Link-Vorabrufung mit next/link
funktioniert nicht routerübergreifend.
Stattdessen können Sie Navigationen optimieren zwischen App Router und Pages Router, um die vorabgerufenen und schnellen Seitenübergänge beizubehalten. Mehr erfahren.
Codemods
Next.js bietet Codemod-Transformationen, um bei der Aktualisierung Ihres Codebase zu helfen, wenn eine Funktion veraltet ist. Weitere Informationen finden Sie unter Codemods.