Next.js

Next.js App Router : migrer depuis Pages Router (guide complet 2026)

Publié le 9 February 2026 — 3 min de lecture
En bref

Migrer depuis le Pages Router vers l'App Router de Next.js est la migration la plus importante de l'écosystème React en 2025-2026. Ce guide pratique vous explique comment migrer progressivement, page par page, sans tout casser.

L’App Router est l’avenir de Next.js. Si vous avez un projet avec le Pages Router (dossier pages/), la question n’est pas “si” migrer mais “quand” et “comment”. Bonne nouvelle : la migration peut se faire progressivement, les deux routers coexistent.

Coexistence Pages Router et App Router

Next.js supporte les deux routers simultanément dans le même projet. Le dossier app/ prend la priorité sur pages/ pour les routes qui existent dans les deux. Stratégie recommandée : ajoutez le dossier app/ et migrez page par page, en commençant par les plus simples.

Différences fondamentales à comprendre

Pages Router : tout est Client Component par défaut. getServerSideProps et getStaticProps pour les données. _app.tsx pour le layout global.

App Router : tout est Server Component par défaut. Les données sont fetchées directement dans les composants async. Les layouts remplacent _app.tsx.

Migrer getStaticProps

// AVANT (Pages Router)
export async function getStaticProps({ params }) {
  const article = await getArticle(params.slug);
  return { props: { article }, revalidate: 3600 };
}
export default function ArticlePage({ article }) {
  return <article>{article.content}</article>;
}

// APRÈS (App Router)
export default async function ArticlePage({ params }) {
  const article = await fetch(`/api/articles/${params.slug}`, {
    next: { revalidate: 3600 }
  }).then(r => r.json());
  return <article>{article.content}</article>;
}

Migrer getServerSideProps

// AVANT
export async function getServerSideProps({ req }) {
  const user = await getUser(req.cookies.session);
  if (!user) return { redirect: { destination: '/login' } };
  return { props: { user } };
}

// APRÈS
import { cookies } from 'next/headers';
import { redirect } from 'next/navigation';

export default async function DashboardPage() {
  const session = cookies().get('session')?.value;
  const user = await getUser(session);
  if (!user) redirect('/login');
  return <div>Bienvenue {user.name}</div>;
}

Migrer les composants avec état

Les composants avec useState, useEffect ou des event handlers doivent être marqués "use client" dans l’App Router :

// AVANT (Pages Router) — fonctionnait sans directive
import { useState } from 'react';
export default function Counter() {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}

// APRÈS (App Router) — directive obligatoire
"use client";
import { useState } from 'react';
export function Counter() {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}

Migrer _app.tsx vers layout.tsx

// AVANT: pages/_app.tsx
export default function App({ Component, pageProps }) {
  return (
    <Providers>
      <Header />
      <Component {...pageProps} />
      <Footer />
    </Providers>
  );
}

// APRÈS: app/layout.tsx
export default function RootLayout({ children }) {
  return (
    <html lang="fr">
      <body>
        <Providers>    {/* "use client" si nécessaire */}
          <Header />   {/* Server Component si pas d'état */}
          <main>{children}</main>
          <Footer />
        </Providers>
      </body>
    </html>
  );
}

Migrer les API routes

// AVANT: pages/api/articles/[slug].ts
export default function handler(req, res) {
  if (req.method !== 'GET') return res.status(405).end();
  const article = await getArticle(req.query.slug);
  res.json(article);
}

// APRÈS: app/api/articles/[slug]/route.ts
export async function GET(request, { params }) {
  const article = await getArticle(params.slug);
  return Response.json(article);
}

Pièges fréquents lors de la migration

Les erreurs les plus courantes : oublier "use client" sur les composants avec hooks React, essayer d’utiliser useRouter de next/router (utilisez next/navigation dans l’App Router), passer des fonctions non-sérialisables comme props d’un Server Component à un Client Component (impossible — utilisez des Server Actions à la place).

W
Rédigé par
WebEngine
Développeur web freelance à Paris spécialisé WordPress, WooCommerce et SEO technique depuis 2010. 13 avis vérifiés · Note 5/5. Chaque site livré atteint un score PageSpeed mobile supérieur à 90.

Un projet en tête ?

Devis gratuit sous 48h, sans engagement.

Demander un devis gratuit