Comment migrer des Pages vers le Routeur App
Ce guide vous aidera à :
- Mettre à jour votre application Next.js de la version 12 à la version 13
- Mettre à niveau les fonctionnalités qui fonctionnent à la fois dans les répertoires
pages
etapp
- Migrer progressivement votre application existante de
pages
versapp
Mise à niveau
Version de Node.js
La version minimale de Node.js est désormais v18.17. Consultez la documentation de Node.js pour plus d'informations.
Version de Next.js
Pour mettre à jour vers Next.js version 13, exécutez la commande suivante avec votre gestionnaire de paquets préféré :
Version d'ESLint
Si vous utilisez ESLint, vous devez mettre à jour votre version d'ESLint :
Bon à savoir : Vous devrez peut-être redémarrer le serveur ESLint dans VS Code pour que les changements d'ESLint prennent effet. Ouvrez la Palette de commandes (
cmd+shift+p
sur Mac ;ctrl+shift+p
sur Windows) et recherchezESLint: Restart ESLint Server
.
Prochaines étapes
Après la mise à jour, consultez les sections suivantes pour les prochaines étapes :
- Mettre à niveau les nouvelles fonctionnalités : Un guide pour vous aider à mettre à niveau vers les nouvelles fonctionnalités telles que les composants Image et Link améliorés.
- Migrer du répertoire
pages
versapp
: Un guide étape par étape pour vous aider à migrer progressivement du répertoirepages
versapp
.
Mise à niveau des nouvelles fonctionnalités
Next.js 13 a introduit le nouveau Routeur App avec de nouvelles fonctionnalités et conventions. Le nouveau Routeur est disponible dans le répertoire app
et coexiste avec le répertoire pages
.
La mise à niveau vers Next.js 13 ne nécessite pas l'utilisation du Routeur App. Vous pouvez continuer à utiliser pages
avec les nouvelles fonctionnalités qui fonctionnent dans les deux répertoires, telles que le composant Image mis à jour, le composant Link, le composant Script et l'optimisation des polices.
Composant <Image/>
Next.js 12 a introduit des améliorations pour le composant Image avec une importation temporaire : next/future/image
. Ces améliorations incluaient moins de JavaScript côté client, des moyens plus simples pour étendre et styliser les images, une meilleure accessibilité et un chargement paresseux natif du navigateur.
Dans la version 13, ce nouveau comportement est maintenant la valeur par défaut pour next/image
.
Il existe deux codemods pour vous aider à migrer vers le nouveau composant Image :
- Codemod
next-image-to-legacy-image
: Renomme de manière sûre et automatique les importsnext/image
ennext/legacy/image
. Les composants existants conserveront le même comportement. - Codemod
next-image-experimental
: Ajoute de manière risquée des styles en ligne et supprime les props inutilisés. Cela modifiera le comportement des composants existants pour correspondre aux nouvelles valeurs par défaut. Pour utiliser ce codemod, vous devez d'abord exécuter le codemodnext-image-to-legacy-image
.
Composant <Link>
Le composant <Link>
ne nécessite plus d'ajouter manuellement une balise <a>
comme enfant. Ce comportement a été ajouté comme option expérimentale dans la version 12.2 et est maintenant la valeur par défaut. Dans Next.js 13, <Link>
rend toujours <a>
et vous permet de transmettre des props à la balise sous-jacente.
Par exemple :
Pour mettre à niveau vos liens vers Next.js 13, vous pouvez utiliser le codemod new-link
.
Composant <Script>
Le comportement de next/script
a été mis à jour pour prendre en charge à la fois pages
et app
, mais certaines modifications doivent être apportées pour assurer une migration fluide :
- Déplacez tous les scripts
beforeInteractive
que vous aviez précédemment inclus dans_document.js
vers le fichier de disposition racine (app/layout.tsx
). - La stratégie expérimentale
worker
ne fonctionne pas encore dansapp
et les scripts désignés avec cette stratégie devront soit être supprimés, soit modifiés pour utiliser une autre stratégie (par exemplelazyOnload
). - Les gestionnaires
onLoad
,onReady
etonError
ne fonctionneront pas dans les composants serveur, alors assurez-vous de les déplacer vers un composant client ou de les supprimer complètement.
Optimisation des polices
Auparavant, Next.js vous aidait à optimiser les polices en intégrant le CSS des polices. La version 13 introduit le nouveau module next/font
qui vous donne la possibilité de personnaliser votre expérience de chargement des polices tout en garantissant des performances et une confidentialité optimales. next/font
est pris en charge dans les répertoires pages
et app
.
Bien que l'intégration du CSS fonctionne toujours dans pages
, elle ne fonctionne pas dans app
. Vous devez utiliser next/font
à la place.
Consultez la page Optimisation des polices pour apprendre à utiliser next/font
.
Migration de pages
vers app
🎥 Regarder : Apprenez à adopter progressivement le Routeur App → YouTube (16 minutes).
Passer au Routeur App peut être la première fois que vous utilisez des fonctionnalités React sur lesquelles Next.js s'appuie, telles que les composants serveur, Suspense, et plus encore. Combinées avec les nouvelles fonctionnalités de Next.js comme les fichiers spéciaux et les dispositions, la migration implique de nouveaux concepts, modèles mentaux et changements de comportement à apprendre.
Nous recommandons de réduire la complexité combinée de ces mises à jour en décomposant votre migration en étapes plus petites. Le répertoire app
est conçu intentionnellement pour fonctionner simultanément avec le répertoire pages
afin de permettre une migration page par page progressive.
- Le répertoire
app
prend en charge les routes imbriquées et les dispositions. En savoir plus. - Utilisez des dossiers imbriqués pour définir les routes et un fichier spécial
page.js
pour rendre un segment de route accessible publiquement. En savoir plus. - Les conventions de fichiers spéciaux sont utilisées pour créer l'interface utilisateur pour chaque segment de route. Les fichiers spéciaux les plus courants sont
page.js
etlayout.js
.- Utilisez
page.js
pour définir une interface utilisateur unique à une route. - Utilisez
layout.js
pour définir une interface utilisateur partagée entre plusieurs routes. - Les extensions de fichiers
.js
,.jsx
ou.tsx
peuvent être utilisées pour les fichiers spéciaux.
- Utilisez
- Vous pouvez colocaliser d'autres fichiers dans le répertoire
app
tels que des composants, des styles, des tests, et plus encore. En savoir plus. - Les fonctions de récupération de données comme
getServerSideProps
etgetStaticProps
ont été remplacées par une nouvelle API dansapp
.getStaticPaths
a été remplacé pargenerateStaticParams
. pages/_app.js
etpages/_document.js
ont été remplacés par une seule disposition racineapp/layout.js
. En savoir plus.pages/_error.js
a été remplacé par des fichiers spéciauxerror.js
plus granulaires. En savoir plus.pages/404.js
a été remplacé par le fichiernot-found.js
.- Les routes API
pages/api/*
ont été remplacées par le fichier spécialroute.js
(Gestionnaire de route).
Étape 1 : Création du répertoire app
Mettez à jour vers la dernière version de Next.js (nécessite la version 13.4 ou supérieure) :
Ensuite, créez un nouveau répertoire app
à la racine de votre projet (ou dans le répertoire src/
).
Étape 2 : Création d'une disposition racine
Créez un nouveau fichier app/layout.tsx
dans le répertoire app
. Il s'agit d'une disposition racine qui s'appliquera à toutes les routes dans app
.
- Le répertoire
app
doit inclure une disposition racine. - La disposition racine doit définir les balises
<html>
et<body>
car Next.js ne les crée pas automatiquement. - La disposition racine remplace les fichiers
pages/_app.tsx
etpages/_document.tsx
. - Les extensions
.js
,.jsx
ou.tsx
peuvent être utilisées pour les fichiers de disposition.
Pour gérer les éléments HTML <head>
, vous pouvez utiliser la prise en charge SEO intégrée :
Migration de _document.js
et _app.js
Si vous avez un fichier _app
ou _document
existant, vous pouvez copier le contenu (par exemple, les styles globaux) dans la disposition racine (app/layout.tsx
). Les styles dans app/layout.tsx
ne s'appliqueront pas à pages/*
. Vous devez conserver _app
/_document
pendant la migration pour éviter de casser vos routes pages/*
. Une fois la migration terminée, vous pouvez les supprimer en toute sécurité.
Si vous utilisez des fournisseurs de contexte React, ils devront être déplacés vers un composant client.
Migration du modèle getLayout()
vers les dispositions (Optionnel)
Next.js recommandait d'ajouter une propriété aux composants Page pour obtenir des dispositions par page dans le répertoire pages
. Ce modèle peut être remplacé par la prise en charge native des dispositions imbriquées dans le répertoire app
.
Voir un exemple avant/après
Avant
Après
-
Supprimez la propriété
Page.getLayout
depages/dashboard/index.js
et suivez les étapes pour migrer les pages vers le répertoireapp
.app/dashboard/page.js -
Déplacez le contenu de
DashboardLayout
dans un nouveau composant client pour conserver le comportement du répertoirepages
.app/dashboard/DashboardLayout.js -
Importez
DashboardLayout
dans un nouveau fichierlayout.js
dans le répertoireapp
.app/dashboard/layout.js -
Vous pouvez déplacer progressivement les parties non interactives de
DashboardLayout.js
(composant client) danslayout.js
(composant serveur) pour réduire la quantité de JavaScript de composant envoyée au client.
Étape 3 : Migration de next/head
Dans le répertoire pages
, le composant React next/head
est utilisé pour gérer les éléments HTML <head>
tels que title
et meta
. Dans le répertoire app
, next/head
est remplacé par la nouvelle prise en charge SEO intégrée.
Avant :
Après :
Voir toutes les options de métadonnées.
Étape 4 : Migration des pages
- Les pages dans le répertoire
app
sont par défaut des Composants Serveur (Server Components). Ceci diffère du répertoirepages
où les pages sont des Composants Client (Client Components). - La récupération de données (Data fetching) a changé dans
app
.getServerSideProps
,getStaticProps
etgetInitialProps
ont été remplacés par une API plus simple. - Le répertoire
app
utilise des dossiers imbriqués pour définir les routes et un fichier spécialpage.js
pour rendre un segment de route accessible publiquement. -
Répertoire pages
Répertoire app
Route index.js
page.js
/
about.js
about/page.js
/about
blog/[slug].js
blog/[slug]/page.js
/blog/post-1
Nous recommandons de décomposer la migration d'une page en deux étapes principales :
- Étape 1 : Déplacer le Composant Page exporté par défaut dans un nouveau Composant Client.
- Étape 2 : Importer le nouveau Composant Client dans un nouveau fichier
page.js
à l'intérieur du répertoireapp
.
Bon à savoir : C'est le chemin de migration le plus simple car il offre le comportement le plus comparable au répertoire
pages
.
Étape 1 : Créer un nouveau Composant Client
- Créez un nouveau fichier séparé dans le répertoire
app
(par exempleapp/home-page.tsx
ou similaire) qui exporte un Composant Client. Pour définir des Composants Client, ajoutez la directive'use client'
en haut du fichier (avant toute importation).- Similaire au Routeur Pages, il y a une étape d'optimisation pour prérendre les Composants Client en HTML statique lors du chargement initial de la page.
- Déplacez le composant de page exporté par défaut de
pages/index.js
versapp/home-page.tsx
.
Étape 2 : Créer une nouvelle page
-
Créez un nouveau fichier
app/page.tsx
dans le répertoireapp
. Ceci est par défaut un Composant Serveur. -
Importez le Composant Client
home-page.tsx
dans la page. -
Si vous récupériez des données dans
pages/index.js
, déplacez la logique de récupération de données directement dans le Composant Serveur en utilisant les nouvelles APIs de récupération de données. Consultez le guide de mise à niveau de la récupération de données pour plus de détails. -
Si votre page précédente utilisait
useRouter
, vous devrez passer aux nouveaux hooks de routage. En savoir plus. -
Démarrez votre serveur de développement et visitez
http://localhost:3000
. Vous devriez voir votre route d'index existante, maintenant servie via le répertoire app.
Étape 5 : Migration des hooks de routage
Un nouveau routeur a été ajouté pour supporter le nouveau comportement dans le répertoire app
.
Dans app
, vous devriez utiliser les trois nouveaux hooks importés depuis next/navigation
: useRouter()
, usePathname()
, et useSearchParams()
.
- Le nouveau hook
useRouter
est importé depuisnext/navigation
et a un comportement différent du hookuseRouter
danspages
qui est importé depuisnext/router
.- Le hook
useRouter
importé depuisnext/router
n'est pas supporté dans le répertoireapp
mais peut continuer à être utilisé dans le répertoirepages
.
- Le hook
- Le nouveau
useRouter
ne retourne pas la chaînepathname
. Utilisez plutôt le hook séparéusePathname
. - Le nouveau
useRouter
ne retourne pas l'objetquery
. Les paramètres de recherche et les paramètres de route dynamique sont maintenant séparés. Utilisez plutôt les hooksuseSearchParams
etuseParams
. - Vous pouvez utiliser
useSearchParams
etusePathname
ensemble pour écouter les changements de page. Voir la section Événements du Routeur (Router Events) pour plus de détails. - Ces nouveaux hooks sont uniquement supportés dans les Composants Client. Ils ne peuvent pas être utilisés dans les Composants Serveur.
De plus, le nouveau hook useRouter
a les changements suivants :
isFallback
a été supprimé carfallback
a été remplacé.- Les valeurs
locale
,locales
,defaultLocales
,domainLocales
ont été supprimées car les fonctionnalités i18n intégrées de Next.js ne sont plus nécessaires dans le répertoireapp
. En savoir plus sur i18n. basePath
a été supprimé. L'alternative ne fera pas partie deuseRouter
. Elle n'a pas encore été implémentée.asPath
a été supprimé car le concept deas
a été retiré du nouveau routeur.isReady
a été supprimé car il n'est plus nécessaire. Pendant le rendu statique (static rendering), tout composant qui utilise le hookuseSearchParams()
sautera l'étape de prérendu et sera plutôt rendu côté client au moment de l'exécution.route
a été supprimé.usePathname
ouuseSelectedLayoutSegments()
fournissent une alternative.
Voir la référence de l'API useRouter()
.
Partage de composants entre pages
et app
Pour garder les composants compatibles entre les routeurs pages
et app
, référez-vous au hook useRouter
depuis next/compat/router
.
Ceci est le hook useRouter
du répertoire pages
, mais destiné à être utilisé lors du partage de composants entre les routeurs. Une fois que vous êtes prêt à l'utiliser uniquement sur le routeur app
, mettez à jour vers le nouveau useRouter
depuis next/navigation
.
Étape 6 : Migration des méthodes de récupération de données
Le répertoire pages
utilise getServerSideProps
et getStaticProps
pour récupérer des données pour les pages. Dans le répertoire app
, ces anciennes fonctions de récupération de données sont remplacées par une API plus simple construite sur fetch()
et les Composants Serveur React asynchrones.
Rendu côté serveur (getServerSideProps
)
Dans le répertoire pages
, getServerSideProps
est utilisé pour récupérer des données côté serveur et transmettre des props au composant React exporté par défaut dans le fichier. Le HTML initial pour la page est prérendu depuis le serveur, suivi par "l'hydratation" de la page dans le navigateur (la rendant interactive).
Dans le Routeur App, nous pouvons colocaliser notre récupération de données à l'intérieur de nos composants React en utilisant des Composants Serveur (Server Components). Cela nous permet d'envoyer moins de JavaScript au client, tout en conservant le HTML rendu depuis le serveur.
En définissant l'option cache
à no-store
, nous pouvons indiquer que les données récupérées ne devraient jamais être mises en cache. Ceci est similaire à getServerSideProps
dans le répertoire pages
.
Accès à l'objet Request
Dans le répertoire pages
, vous pouvez récupérer des données basées sur la requête en utilisant l'API HTTP de Node.js.
Par exemple, vous pouvez récupérer l'objet req
depuis getServerSideProps
et l'utiliser pour récupérer les cookies et en-têtes de la requête.
Le répertoire app
expose de nouvelles fonctions en lecture seule pour récupérer les données de la requête :
headers
: Basée sur l'API Web Headers, et peut être utilisée dans les Composants Serveur (Server Components) pour récupérer les en-têtes de la requête.cookies
: Basée sur l'API Web Cookies, et peut être utilisée dans les Composants Serveur (Server Components) pour récupérer les cookies.
Génération de site statique (getStaticProps
)
Dans le répertoire pages
, la fonction getStaticProps
est utilisée pour prérendre une page au moment de la construction. Cette fonction peut être utilisée pour récupérer des données depuis une API externe ou directement depuis une base de données, et transmettre ces données à toute la page pendant sa génération au moment de la construction.
Dans le répertoire app
, la récupération de données avec fetch()
utilisera par défaut cache: 'force-cache'
, ce qui mettra en cache les données de la requête jusqu'à invalidation manuelle. Ceci est similaire à getStaticProps
dans le répertoire pages
.
Chemins dynamiques (getStaticPaths
)
Dans le répertoire pages
, la fonction getStaticPaths
est utilisée pour définir les chemins dynamiques qui doivent être pré-rendus au moment de la construction.
Dans le répertoire app
, getStaticPaths
est remplacé par generateStaticParams
.
generateStaticParams
se comporte de manière similaire à getStaticPaths
, mais offre une API simplifiée pour retourner les paramètres de route et peut être utilisée à l'intérieur des layouts. Le format de retour de generateStaticParams
est un tableau de segments au lieu d'un tableau d'objets param
imbriqués ou d'une chaîne de chemins résolus.
L'utilisation du nom generateStaticParams
est plus appropriée que getStaticPaths
pour le nouveau modèle dans le répertoire app
. Le préfixe get
est remplacé par un terme plus descriptif generate
, qui se suffit mieux maintenant que getStaticProps
et getServerSideProps
ne sont plus nécessaires. Le suffixe Paths
est remplacé par Params
, qui est plus adapté pour le routage imbriqué avec plusieurs segments dynamiques.
Remplacer fallback
Dans le répertoire pages
, la propriété fallback
retournée par getStaticPaths
est utilisée pour définir le comportement d'une page qui n'est pas pré-rendue au moment de la construction. Cette propriété peut être définie à true
pour afficher une page de secours pendant que la page est générée, false
pour afficher une page 404, ou blocking
pour générer la page au moment de la requête.
Dans le répertoire app
, la propriété config.dynamicParams
contrôle la gestion des paramètres non inclus dans generateStaticParams
:
true
: (par défaut) Les segments dynamiques non inclus dansgenerateStaticParams
sont générés à la demande.false
: Les segments dynamiques non inclus dansgenerateStaticParams
retourneront une erreur 404.
Cela remplace l'option fallback: true | false | 'blocking'
de getStaticPaths
dans le répertoire pages
. L'option fallback: 'blocking'
n'est pas incluse dans dynamicParams
car la différence entre 'blocking'
et true
est négligeable avec le streaming.
Avec dynamicParams
défini à true
(valeur par défaut), lorsqu'un segment de route qui n'a pas été généré est demandé, il sera rendu côté serveur et mis en cache.
Régénération statique incrémentale (getStaticProps
avec revalidate
)
Dans le répertoire pages
, la fonction getStaticProps
permet d'ajouter un champ revalidate
pour régénérer automatiquement une page après un certain temps.
Dans le répertoire app
, la récupération de données avec fetch()
peut utiliser revalidate
, qui mettra en cache la requête pour un nombre de secondes spécifié.
Routes API
Les routes API continuent de fonctionner dans le répertoire pages/api
sans aucun changement. Cependant, elles ont été remplacées par les Route Handlers dans le répertoire app
.
Les Route Handlers permettent de créer des gestionnaires de requêtes personnalisés pour une route donnée en utilisant les API Web Request et Response.
Bon à savoir : Si vous utilisiez auparavant les routes API pour appeler une API externe depuis le client, vous pouvez maintenant utiliser les Composants Serveur pour récupérer des données de manière sécurisée. En savoir plus sur la récupération de données.
Applications monopages
Si vous migrez également vers Next.js depuis une application monopage (SPA), consultez notre documentation pour en savoir plus.
Étape 7 : Stylisation
Dans le répertoire pages
, les feuilles de style globales sont restreintes à pages/_app.js
. Avec le répertoire app
, cette restriction a été levée. Les styles globaux peuvent être ajoutés à n'importe quel layout, page ou composant.
Tailwind CSS
Si vous utilisez Tailwind CSS, vous devrez ajouter le répertoire app
à votre fichier tailwind.config.js
:
Vous devrez également importer vos styles globaux dans votre fichier app/layout.js
:
En savoir plus sur la stylisation avec Tailwind CSS
Utilisation conjointe du routeur App et du routeur Pages
Lors de la navigation entre les routes gérées par les différents routeurs Next.js, il y aura une navigation dure. Le préchargement automatique des liens avec next/link
ne préchargera pas entre les routeurs.
À la place, vous pouvez optimiser les navigations entre le routeur App et le routeur Pages pour conserver les transitions de page préchargées et rapides. En savoir plus.
Codemods
Next.js fournit des transformations Codemod pour aider à mettre à jour votre base de code lorsqu'une fonctionnalité est dépréciée. Voir Codemods pour plus d'informations.