Comment migrer des Pages vers l'App Router

Ce guide vous aidera à :

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é :

Terminal
npm install next@latest react@latest react-dom@latest

Version d'ESLint

Si vous utilisez ESLint, vous devez mettre à jour votre version d'ESLint :

Terminal
npm install -D eslint-config-next@latest

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 recherchez ESLint: Restart ESLint Server.

Prochaines étapes

Après la mise à jour, consultez les sections suivantes pour les prochaines étapes :

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 imports next/image en next/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 codemod next-image-to-legacy-image.

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 :

import Link from 'next/link'

// Next.js 12 : `<a>` doit être imbriqué sinon il est exclu
<Link href="/about">
  <a>About</a>
</Link>

// Next.js 13 : `<Link>` rend toujours `<a>` en arrière-plan
<Link href="/about">
  About
</Link>

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 dans app 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 exemple lazyOnload).
  • Les gestionnaires onLoad, onReady et onError 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 et layout.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.
  • 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 et getStaticProps ont été remplacées par une nouvelle API dans app. getStaticPaths a été remplacé par generateStaticParams.
  • pages/_app.js et pages/_document.js ont été remplacés par une seule disposition racine app/layout.js. En savoir plus.
  • pages/_error.js a été remplacé par des fichiers spéciaux error.js plus granulaires. En savoir plus.
  • pages/404.js a été remplacé par le fichier not-found.js.
  • Les routes API pages/api/* ont été remplacées par le fichier spécial route.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) :

npm install next@latest

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.

export default function RootLayout({
  // Les dispositions doivent accepter une prop children.
  // Ceci sera rempli avec des dispositions ou des pages imbriquées
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}
  • 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 et pages/_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 :

import type { Metadata } from 'next'

export const metadata: Metadata = {
  title: 'Accueil',
  description: 'Bienvenue sur Next.js',
}

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

components/DashboardLayout.js
export default function DashboardLayout({ children }) {
  return (
    <div>
      <h2>Mon Tableau de bord</h2>
      {children}
    </div>
  )
}
pages/dashboard/index.js
import DashboardLayout from '../components/DashboardLayout'

export default function Page() {
  return <p>Ma Page</p>
}

Page.getLayout = function getLayout(page) {
  return <DashboardLayout>{page}</DashboardLayout>
}

Après

  • Supprimez la propriété Page.getLayout de pages/dashboard/index.js et suivez les étapes pour migrer les pages vers le répertoire app.

    app/dashboard/page.js
    export default function Page() {
      return <p>Ma Page</p>
    }
  • Déplacez le contenu de DashboardLayout dans un nouveau composant client pour conserver le comportement du répertoire pages.

    app/dashboard/DashboardLayout.js
    'use client' // cette directive doit être en haut du fichier, avant toute importation.
    
    // Ceci est un composant client
    export default function DashboardLayout({ children }) {
      return (
        <div>
          <h2>Mon Tableau de bord</h2>
          {children}
        </div>
      )
    }
  • Importez DashboardLayout dans un nouveau fichier layout.js dans le répertoire app.

    app/dashboard/layout.js
    import DashboardLayout from './DashboardLayout'
    
    // Ceci est un composant serveur
    export default function Layout({ children }) {
      return <DashboardLayout>{children}</DashboardLayout>
    }
  • Vous pouvez déplacer progressivement les parties non interactives de DashboardLayout.js (composant client) dans layout.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 :

import Head from 'next/head'

export default function Page() {
  return (
    <>
      <Head>
        <title>Titre de ma page</title>
      </Head>
    </>
  )
}

Après :

import type { Metadata } from 'next'

export const metadata: Metadata = {
  title: 'Titre de ma page',
}

export default function Page() {
  return '...'
}

Voir toutes les options de métadonnées.

Étape 4 : Migration des pages

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épertoire app.

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 exemple app/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 vers app/home-page.tsx.
'use client'

// Ceci est un Composant Client (identique aux composants dans le répertoire `pages`)
// Il reçoit des données comme props, a accès à l'état et aux effets, et est
// prérendu sur le serveur lors du chargement initial de la page.
export default function HomePage({ recentPosts }) {
  return (
    <div>
      {recentPosts.map((post) => (
        <div key={post.id}>{post.title}</div>
      ))}
    </div>
  )
}

Étape 2 : Créer une nouvelle page

  • Créez un nouveau fichier app/page.tsx dans le répertoire app. 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.

    // Importez votre Composant Client
    import HomePage from './home-page'
    
    async function getPosts() {
      const res = await fetch('https://...')
      const posts = await res.json()
      return posts
    }
    
    export default async function Page() {
      // Récupérez les données directement dans un Composant Serveur
      const recentPosts = await getPosts()
      // Transmettez les données récupérées à votre Composant Client
      return <HomePage recentPosts={recentPosts} />
    }
  • 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é depuis next/navigation et a un comportement différent du hook useRouter dans pages qui est importé depuis next/router.
  • Le nouveau useRouter ne retourne pas la chaîne pathname. Utilisez plutôt le hook séparé usePathname.
  • Le nouveau useRouter ne retourne pas l'objet query. Les paramètres de recherche et les paramètres de route dynamique sont maintenant séparés. Utilisez plutôt les hooks useSearchParams et useParams.
  • Vous pouvez utiliser useSearchParams et usePathname 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.
'use client'

import { useRouter, usePathname, useSearchParams } from 'next/navigation'

export default function ExampleClientComponent() {
  const router = useRouter()
  const pathname = usePathname()
  const searchParams = useSearchParams()

  // ...
}

De plus, le nouveau hook useRouter a les changements suivants :

  • isFallback a été supprimé car fallback 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épertoire app. En savoir plus sur i18n.
  • basePath a été supprimé. L'alternative ne fera pas partie de useRouter. Elle n'a pas encore été implémentée.
  • asPath a été supprimé car le concept de as 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 hook useSearchParams() 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 ou useSelectedLayoutSegments() 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.

export default async function Page() {
  // Cette requête devrait être mise en cache jusqu'à invalidation manuelle.
  // Similaire à `getStaticProps`.
  // `force-cache` est la valeur par défaut et peut être omis.
  const staticData = await fetch(`https://...`, { cache: 'force-cache' })

  // Cette requête devrait être récupérée à chaque requête.
  // Similaire à `getServerSideProps`.
  const dynamicData = await fetch(`https://...`, { cache: 'no-store' })

  // Cette requête devrait être mise en cache avec une durée de vie de 10 secondes.
  // Similaire à `getStaticProps` avec l'option `revalidate`.
  const revalidatedData = await fetch(`https://...`, {
    next: { revalidate: 10 },
  })

  return <div>...</div>
}

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).

pages/dashboard.js
// Répertoire `pages`

export async function getServerSideProps() {
  const res = await fetch(`https://...`)
  const projects = await res.json()

  return { props: { projects } }
}

export default function Dashboard({ projects }) {
  return (
    <ul>
      {projects.map((project) => (
        <li key={project.id}>{project.name}</li>
      ))}
    </ul>
  )
}

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.

// Répertoire `app`

// Cette fonction peut être nommée comme vous voulez
async function getProjects() {
  const res = await fetch(`https://...`, { cache: 'no-store' })
  const projects = await res.json()

  return projects
}

export default async function Dashboard() {
  const projects = await getProjects()

  return (
    <ul>
      {projects.map((project) => (
        <li key={project.id}>{project.name}</li>
      ))}
    </ul>
  )
}

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.

pages/index.js
// Répertoire `pages`

export async function getServerSideProps({ req, query }) {
  const authHeader = req.getHeaders()['authorization'];
  const theme = req.cookies['theme'];

  return { props: { ... }}
}

export default function Page(props) {
  return ...
}

Le répertoire app expose de nouvelles fonctions en lecture seule pour récupérer les données de la requête :

// Répertoire `app`
import { cookies, headers } from 'next/headers'

async function getData() {
  const authHeader = (await headers()).get('authorization')

  return '...'
}

export default async function Page() {
  // Vous pouvez utiliser `cookies` ou `headers` dans les Composants Serveur
  // directement ou dans votre fonction de récupération de données
  const theme = (await cookies()).get('theme')
  const data = await getData()
  return '...'
}

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.

pages/index.js
// Répertoire `pages`

export async function getStaticProps() {
  const res = await fetch(`https://...`)
  const projects = await res.json()

  return { props: { projects } }
}

export default function Index({ projects }) {
  return projects.map((project) => <div>{project.name}</div>)
}

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.

app/page.js
// Répertoire `app`

// Cette fonction peut être nommée comme vous voulez
async function getProjects() {
  const res = await fetch(`https://...`)
  const projects = await res.json()

  return projects
}

export default async function Index() {
  const projects = await getProjects()

  return projects.map((project) => <div>{project.name}</div>)
}

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.

pages/posts/[id].js
// Répertoire `pages`
import PostLayout from '@/components/post-layout'

export async function getStaticPaths() {
  return {
    paths: [{ params: { id: '1' } }, { params: { id: '2' } }],
  }
}

export async function getStaticProps({ params }) {
  const res = await fetch(`https://.../posts/${params.id}`)
  const post = await res.json()

  return { props: { post } }
}

export default function Post({ post }) {
  return <PostLayout post={post} />
}

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.

app/posts/[id]/page.js
// Répertoire `app`
import PostLayout from '@/components/post-layout'

export async function generateStaticParams() {
  return [{ id: '1' }, { id: '2' }]
}

async function getPost(params) {
  const res = await fetch(`https://.../posts/${(await params).id}`)
  const post = await res.json()

  return post
}

export default async function Post({ params }) {
  const post = await getPost(params)

  return <PostLayout post={post} />
}

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.

pages/posts/[id].js
// Répertoire `pages`

export async function getStaticPaths() {
  return {
    paths: [],
    fallback: 'blocking'
  };
}

export async function getStaticProps({ params }) {
  ...
}

export default function Post({ post }) {
  return ...
}

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 dans generateStaticParams sont générés à la demande.
  • false : Les segments dynamiques non inclus dans generateStaticParams 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.

app/posts/[id]/page.js
// Répertoire `app`

export const dynamicParams = true;

export async function generateStaticParams() {
  return [...]
}

async function getPost(params) {
  ...
}

export default async function Post({ params }) {
  const post = await getPost(params);

  return ...
}

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.

pages/index.js
// Répertoire `pages`

export async function getStaticProps() {
  const res = await fetch(`https://.../posts`)
  const posts = await res.json()

  return {
    props: { posts },
    revalidate: 60,
  }
}

export default function Index({ posts }) {
  return (
    <Layout>
      <PostList posts={posts} />
    </Layout>
  )
}

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é.

app/page.js
// Répertoire `app`

async function getPosts() {
  const res = await fetch(`https://.../posts`, { next: { revalidate: 60 } })
  const data = await res.json()

  return data.posts
}

export default async function PostList() {
  const posts = await getPosts()

  return posts.map((post) => <div>{post.name}</div>)
}

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.

export async function GET(request: Request) {}

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 :

tailwind.config.js
module.exports = {
  content: [
    './app/**/*.{js,ts,jsx,tsx,mdx}', // <-- Ajoutez cette ligne
    './pages/**/*.{js,ts,jsx,tsx,mdx}',
    './components/**/*.{js,ts,jsx,tsx,mdx}',
  ],
}

Vous devrez également importer vos styles globaux dans votre fichier app/layout.js :

app/layout.js
import '../styles/globals.css'

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}

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.