Migrationsanleitung für den App Router
Diese Anleitung hilft Ihnen:
- Next.js-Anwendung von Version 12 auf Version 13 aktualisieren
- Features upgraden, die in beiden Verzeichnissen,
pages
undapp
, funktionieren - Bestehende Anwendung schrittweise von
pages
nachapp
migrieren
Upgrade
Node.js-Version
Die minimale Node.js-Version ist jetzt 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 folgenden Befehl mit Ihrem bevorzugten Paketmanager aus:
ESLint-Version
Wenn Sie ESLint verwenden, müssen Sie Ihre ESLint-Version upgraden:
Hinweis: Möglicherweise müssen Sie den ESLint-Server in VS Code neu starten, damit die Ä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 dem Update sehen Sie sich die folgenden Abschnitte für die nächsten Schritte an:
- Neue Features upgraden: Eine Anleitung zum Upgrade neuer Features wie der verbesserten Bild- und Link-Komponenten.
- Migration vom
pages
- zumapp
-Verzeichnis: Eine Schritt-für-Schritt-Anleitung zur schrittweisen Migration vompages
- zumapp
-Verzeichnis.
Neue Features upgraden
Next.js 13 führte den neuen App Router mit neuen Features und Konventionen ein. Der neue Router ist im app
-Verzeichnis verfügbar und koexistiert mit dem pages
-Verzeichnis.
Das Upgrade auf Next.js 13 erfordert nicht die Nutzung des neuen App Routers. Sie können pages
weiterhin mit neuen Features verwenden, die in beiden Verzeichnissen funktionieren, wie die aktualisierte Bild-Komponente, Link-Komponente, Script-Komponente und Schriftartenoptimierung.
<Image/>
-Komponente
Next.js 12 führte Verbesserungen an der Bild-Komponente mit einer temporären Import: next/future/image
ein. Diese Verbesserungen umfassten weniger Client-seitiges JavaScript, einfachere Möglichkeiten zum Erweitern und Gestalten von Bildern, bessere Barrierefreiheit und natives Browser-Lazy-Loading.
In Version 13 ist dieses neue Verhalten jetzt der Standard für next/image
.
Es gibt zwei Codemods, um Ihnen bei der Migration zur neuen Bild-Komponente zu helfen:
next-image-to-legacy-image
Codemod: Benenntnext/image
-Importe sicher und automatisch zunext/legacy/image
um. Bestehende Komponenten behalten das gleiche Verhalten bei.next-image-experimental
Codemod: Fügt gefährlich Inline-Stile hinzu und entfernt ungenutzte Props. Dies ändert das Verhalten bestehender Komponenten, um den neuen Standardeinstellungen 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 untergeordnetes Element. Dieses Verhalten wurde in Version 12.2 als experimentelle Option hinzugefügt und ist jetzt der Standard. In Next.js 13 rendert <Link>
immer <a>
und ermöglicht Ihnen, Props an das zugrunde liegende Tag weiterzuleiten.
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 müssen vorgenommen werden, um eine reibungslose Migration sicherzustellen:
- Verschieben Sie alle
beforeInteractive
-Skripte, die Sie zuvor in_document.js
eingefügt haben, in die Root-Layout-Datei (app/layout.tsx
). - Die experimentelle
worker
-Strategie funktioniert noch nicht inapp
, und Skripte, die mit dieser Strategie gekennzeichnet sind, müssen entweder entfernt oder so geändert werden, dass sie eine andere Strategie verwenden (z. B.lazyOnload
). onLoad
-,onReady
- undonError
-Handler funktionieren nicht in Server-Komponenten, stellen Sie also sicher, dass Sie sie in eine Client-Komponente verschieben oder vollständig entfernen.
Schriftartenoptimierung
Bisher half Ihnen Next.js bei der Optimierung von Schriftarten durch Inline-Setzen von Schriftarten-CSS. Version 13 führt das neue next/font
-Modul ein, das Ihnen die Möglichkeit gibt, Ihre Schriftartenladevorgänge anzupassen und gleichzeitig eine hervorragende Leistung und Privatsphäre zu gewährleisten. next/font
wird in beiden Verzeichnissen, pages
und app
, 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 Schriftartenoptimierung.
Migration von pages
zu app
🎥 Anschauen: Lernen Sie, wie Sie den App Router schrittweise einführen → YouTube (16 Minuten).
Der Wechsel zum App Router ist möglicherweise das erste Mal, dass Sie React-Features verwenden, auf denen Next.js aufbaut, wie Server-Komponenten, Suspense und mehr. In Kombination mit neuen Next.js-Features wie spezielle Dateien und Layouts bedeutet die Migration das Erlernen neuer Konzepte, Denkmodelle und Verhaltensänderungen.
Wir empfehlen, die kombinierte Komplexität dieser Updates 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 Seitenmigrationen zu ermöglichen.
- Das
app
-Verzeichnis unterstützt verschachtelte Routen und Layouts. Mehr erfahren. - Verwenden Sie verschachtelte Ordner zum Definieren von Routen und eine spezielle
page.js
-Datei, um ein Routensegment öffentlich zugänglich zu machen. Mehr erfahren. - Spezielle Dateikonventionen werden verwendet, um die Benutzeroberfläche für jedes Routensegment zu erstellen. Die häufigsten speziellen Dateien sind
page.js
undlayout.js
.- Verwenden Sie
page.js
, um eine für eine Route einzigartige Benutzeroberfläche zu definieren. - Verwenden Sie
layout.js
, um eine Benutzeroberfläche zu definieren, die über mehrere Routen hinweg geteilt wird. .js
,.jsx
oder.tsx
Dateierweiterungen können für spezielle Dateien verwendet werden.
- Verwenden Sie
- Sie können andere Dateien wie Komponenten, Stile, Tests und mehr im
app
-Verzeichnis zusammen ablegen. Mehr erfahren. - Datenabruffunktionen wie
getServerSideProps
undgetStaticProps
wurden durch eine neue API imapp
-Verzeichnis 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 granularereerror.js
-Spezialdateien ersetzt. Mehr erfahren.pages/404.js
wurde durch dienot-found.js
-Datei ersetzt.pages/api/*
API-Routen wurden durch dieroute.js
(Route Handler) Spezialdatei 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 im app
-Verzeichnis 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. .js
,.jsx
oder.tsx
Erweiterungen können für Layout-Dateien verwendet werden.
Um <head>
-HTML-Elemente zu verwalten, können Sie die integrierte SEO-Unterstützung verwenden:
Migrieren von _document.js
und _app.js
Wenn Sie eine bestehende _app
- oder _document
-Datei haben, können Sie die Inhalte (z.B. globale Stile) in das Root-Layout (app/layout.tsx
) kopieren. Stile in app/layout.tsx
werden nicht auf pages/*
angewendet. Sie sollten _app
/_document
während der Migration beibehalten, um zu verhindern, dass Ihre pages/*
-Routen unterbrochen werden. Sobald die Migration vollständig ist, können Sie sie sicher löschen.
Wenn Sie React-Kontextanbieter verwenden, müssen diese in eine Client-Komponente verschoben werden.
Migrieren des getLayout()
-Musters zu Layouts (optional)
Next.js empfahl das Hinzufügen einer Eigenschaft zu Seitenkomponenten im pages
-Verzeichnis, um seitenspezifische Layouts zu erreichen. Dieses Muster kann durch native Unterstützung für verschachtelte Layouts im app
-Verzeichnis ersetzt werden.
Beispiel vor und nach der Änderung
Vorher
Nachher
-
Entfernen Sie die
Page.getLayout
-Eigenschaft auspages/dashboard/index.js
und folgen Sie den Schritten zum Migrieren von Seiten in dasapp
-Verzeichnis. -
Verschieben Sie den Inhalt von
DashboardLayout
in eine neue Client-Komponente, um das Verhalten despages
-Verzeichnisses beizubehalten. -
Importieren Sie das
DashboardLayout
in eine neuelayout.js
-Datei imapp
-Verzeichnis. -
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 an den Client gesendet wird.
Schritt 3: Migrieren 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 Metadaten-Optionen ansehen.
Schritt 4: Migrieren von Seiten
- Seiten im
app
-Verzeichnis sind standardmäßig Server-Komponenten. Dies unterscheidet sich vompages
-Verzeichnis, in dem Seiten Client-Komponenten sind. - Datenabruf hat sich im
app
-Verzeichnis geändert.getServerSideProps
,getStaticProps
undgetInitialProps
wurden durch eine einfachere API ersetzt. - Das
app
-Verzeichnis verwendet verschachtelte Ordner zum Definieren von Routen 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 Hauptschritten durchzuführen:
- Schritt 1: Verschieben Sie die standardmäßig exportierte Seitenkomponente in eine neue Client-Komponente.
- Schritt 2: Importieren Sie die neue Client-Komponente in eine neue
page.js
-Datei imapp
-Verzeichnis.
Hinweis: 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'
-Anweisung am Anfang der Datei hinzu (vor allen Importen).- Ähnlich wie im Pages Router gibt es einen Optimierungsschritt, um Client-Komponenten beim ersten Seitenaufruf zu statischem HTML vorzurendern.
- Verschieben Sie die standardmäßig exportierte Seitenkomponente 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. -
Wenn Sie Daten in
pages/index.js
abgerufen haben, verschieben Sie die Datenabruf-Logik direkt in die Server-Komponente mithilfe der neuen Datenabruf-APIs. Weitere Details finden Sie im Datenabruf-Upgrade-Leitfaden. -
Wenn Ihre vorherige Seite
useRouter
verwendet hat, müssen Sie auf die neuen Routing-Hooks umstellen. Weitere Informationen. -
Starten Sie Ihren Entwicklungsserver und besuchen Sie
http://localhost:3000
. Sie sollten Ihre bestehende Index-Route sehen, die jetzt über das App-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 aus next/navigation
verwenden: useRouter()
, usePathname()
und useSearchParams()
.
- Der neue
useRouter
-Hook wird ausnext/navigation
importiert und hat ein anderes Verhalten als deruseRouter
-Hook inpages
, der ausnext/router
importiert wird.- Der
useRouter
-Hook ausnext/router
wird imapp
-Verzeichnis nicht unterstützt, kann aber impages
-Verzeichnis weiterverwendet werden.
- Der
- Der neue
useRouter
gibt denpathname
-String nicht zurück. Verwenden Sie stattdessen den separatenusePathname
-Hook. - Der neue
useRouter
gibt dasquery
-Objekt nicht zurück. Suchparameter und dynamische Routenparameter sind jetzt getrennt. Verwenden Sie stattdessen dieuseSearchParams
- unduseParams
-Hooks. - Sie können
useSearchParams
undusePathname
zusammen verwenden, um Seitenwechsel zu überwachen. Weitere Details finden Sie im Abschnitt Router-Ereignisse. - Diese neuen Hooks werden nur in Client-Komponenten unterstützt. Sie können nicht in Server-Komponenten verwendet werden.
Zusätzlich hat der neue useRouter
-Hook folgende Änderungen:
isFallback
wurde entfernt, dafallback
ersetzt wurde.- Die Werte
locale
,locales
,defaultLocales
,domainLocales
wurden entfernt, da integrierte i18n-Funktionen von Next.js imapp
-Verzeichnis nicht mehr erforderlich sind. Weitere Informationen zu i18n. basePath
wurde entfernt. Die Alternative wird nicht Teil vonuseRouter
sein. Es wurde noch nicht implementiert.asPath
wurde entfernt, da das Konzept vonas
aus dem neuen Router entfernt wurde.isReady
wurde entfernt, da es nicht mehr erforderlich ist. Während des statischen Renderings überspringt jede Komponente, die denuseSearchParams()
-Hook verwendet, den Vorrendering-Schritt und wird stattdessen zur Laufzeit auf dem Client gerendert.route
wurde entfernt.usePathname
oderuseSelectedLayoutSegments()
bieten eine Alternative.
API-Referenz für useRouter()
anzeigen.
Komponenten zwischen pages
und app
teilen
Um Komponenten zwischen den pages
und app
Routern kompatibel zu halten, verwenden Sie den useRouter
Hook aus next/compat/router
.
Dies ist der useRouter
Hook aus dem pages
-Verzeichnis, der jedoch dazu gedacht ist, Komponenten zwischen Routern zu teilen. Sobald Sie bereit sind, ihn nur im app
-Router zu verwenden, aktualisieren Sie auf den neuen useRouter
aus next/navigation
.
Schritt 6: Migration von Daten-Abrufmethoden
Das pages
-Verzeichnis verwendet getServerSideProps
und getStaticProps
, um Daten für Seiten abzurufen. Im app
-Verzeichnis werden diese vorherigen Daten-Abruffunktionen durch eine einfachere API ersetzt, die auf fetch()
und async
React Server Components aufbaut.
Server-Side Rendering (getServerSideProps
)
Im pages
-Verzeichnis wird getServerSideProps
verwendet, um Daten auf dem Server abzurufen und Props an die standardmäßig exportierte React-Komponente in der Datei weiterzuleiten. Die ursprüngliche HTML-Seite wird vom Server vorgerendert, gefolgt vom "Hydratisieren" der Seite im Browser (interaktiv machen).
Im App Router können wir unseren Daten-Abruf innerhalb unserer React-Komponenten mit Server Components zusammenführen. Dies ermöglicht es uns, weniger JavaScript an den Client zu senden und gleichzeitig die gerenderte HTML vom Server beizubehalten.
Indem wir die cache
-Option auf no-store
setzen, können wir angeben, dass die abgerufenen Daten niemals zwischengespeichert werden sollen. Dies ähnelt getServerSideProps
im pages
-Verzeichnis.
Zugriff auf das Request-Objekt
Im pages
-Verzeichnis können Sie anfragenbezogene Daten basierend auf der Node.js HTTP-API abrufen.
Beispielsweise können Sie das req
-Objekt aus getServerSideProps
abrufen und es verwenden, um die Cookies und Header der Anfrage abzurufen.
Das app
-Verzeichnis stellt neue schreibgeschützte Funktionen bereit, um Anfragedaten abzurufen:
headers
: Basierend auf der Web Headers API und kann innerhalb von Server Components verwendet werden, um Anfrage-Header abzurufen.cookies
: Basierend auf der Web Cookies API und kann innerhalb von Server Components verwendet werden, um Cookies abzurufen.
Statische Seitengenerierung (getStaticProps
)
Im pages
-Verzeichnis wird die getStaticProps
-Funktion verwendet, um eine Seite zur Bauzeit vorher zu rendern. Diese Funktion kann verwendet werden, um Daten von einer externen API oder direkt aus einer Datenbank abzurufen und diese Daten während der Erstellung an die gesamte Seite weiterzugeben.
Im app
-Verzeichnis wird der Daten-Abruf mit fetch()
standardmäßig auf cache: 'force-cache'
gesetzt, was die Anfragedaten so lange zwischenspeichert, bis sie manuell für ungültig erklärt werden. Dies ähnelt getStaticProps
im pages
-Verzeichnis.
Dynamische Pfade (getStaticPaths
)
Im pages
-Verzeichnis wird die getStaticPaths
-Funktion verwendet, um die dynamischen Pfade zu definieren, die zur Bauzeit vorher gerendert werden sollen.
Im app
-Verzeichnis wird getStaticPaths
durch generateStaticParams
ersetzt.
generateStaticParams
verhält sich ähnlich wie getStaticPaths
, hat jedoch eine vereinfachte API zum Zurückgeben von Routenparametern und kann in Layouts verwendet werden. Die Rückgabestruktur von generateStaticParams
ist ein Array von Segmenten anstelle eines Arrays von verschachtelten param
-Objekten oder einer Zeichenfolge von aufgelösten Pfaden.
Die Verwendung des Namens generateStaticParams
ist für das neue Modell im app
-Verzeichnis passender als getStaticPaths
. Das Präfix get
wird durch das beschreibendere generate
ersetzt, was jetzt besser allein funktioniert, da getStaticProps
und getServerSideProps
nicht mehr erforderlich sind. Das Suffix Paths
wird durch Params
ersetzt, was für verschachtelte Routing mit mehreren dynamischen Segmenten angemessener ist.
Ersetzen von fallback
Im pages
-Verzeichnis wird die fallback
-Eigenschaft, die von getStaticPaths
zurückgegeben wird, verwendet, um das Verhalten einer Seite zu definieren, die zur Bauzeit nicht vorgerendert wurde. Diese Eigenschaft kann auf true
gesetzt werden, um eine Fallback-Seite während der Seitengenerierung anzuzeigen, auf false
, um eine 404-Seite anzuzeigen, oder auf blocking
, um die Seite zum Anfragezeitpunkt zu generieren.
Im app
-Verzeichnis steuert die Eigenschaft config.dynamicParams
, wie Parameter außerhalb von generateStaticParams
behandelt werden:
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
beim Streaming vernachlässigbar ist.
Bei dynamicParams
, das auf true
(Standard) gesetzt ist, wird bei einer Anfrage eines Routensegments, das nicht generiert wurde, dieses serverseitig gerendert und zwischengespeichert.
Inkrementelle statische Regenerierung (getStaticProps
mit revalidate
)
Im pages
-Verzeichnis ermöglicht die Funktion getStaticProps
das Hinzufügen eines revalidate
-Feldes, um eine Seite nach einer bestimmten Zeit automatisch neu zu generieren.
Im app
-Verzeichnis kann Datenabruf mit fetch()
revalidate
verwenden, was die Anfrage für die angegebene Anzahl von Sekunden zwischenspeichert.
API-Routen
API-Routen funktionieren weiterhin im Verzeichnis pages/api
ohne Änderungen. Sie wurden jedoch im app
-Verzeichnis durch Route-Handler ersetzt.
Route-Handler ermöglichen das Erstellen benutzerdefinierter Anforderungshandler für eine bestimmte Route mithilfe der Web Request- und Response-APIs.
Hinweis: Wenn Sie zuvor API-Routen verwendet haben, um eine externe API vom Client aus aufzurufen, können Sie jetzt stattdessen Server-Komponenten verwenden, um Daten sicher abzurufen. Weitere Informationen zum Datenabruf.
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 Stile können zu jedem Layout, jeder Seite oder 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 Stile in Ihre app/layout.js
-Datei importieren:
Weitere Informationen zum Styling mit Tailwind CSS
Codemods
Next.js bietet Codemod-Transformationen, um das Upgrade Ihrer Codebasis zu unterstützen, wenn ein Feature veraltet ist. Weitere Informationen finden Sie unter Codemods.