Frontend·2 min de lecture

Next.js : l'App Router

L'idée clé

Avec Next.js App Router, la structure des dossiers est ta hiérarchie d'URL. Tu ne déclares plus de routes dans un fichier de config (comme urls.py en Django) : Next lit l'arborescence sous app/ (ou src/app/) et chaque dossier devient un segment d'URL.

app/
├── page.tsx              → GET /
├── admin/
│   ├── page.tsx          → GET /admin
│   └── produits/
│       └── page.tsx      → GET /admin/produits
└── api/
    └── panier/
        └── route.ts      → /api/panier (handlers HTTP : GET, POST, etc.)

Les fichiers à conventions strictes

Chaque dossier peut contenir des fichiers avec un nom réservé qui jouent un rôle précis :

FichierRôle
page.tsxLa page elle-même (rendue à cette URL)
layout.tsxCoquille englobante (header, sidebar, etc.) — voir l'article dédié
loading.tsxUI affichée pendant que page.tsx charge ses données
error.tsxUI affichée si page.tsx plante
not-found.tsxUI affichée si notFound() est appelé
route.tsHandler API (pas une page) — exporte GET, POST, etc.

Routes dynamiques : [slug]

Un dossier entre crochets capture la valeur dans l'URL :

app/products/[id]/page.tsx   → /products/42, /products/abc, etc.

Dans la page, tu reçois params.id (en Next 15+, c'est un Promise à await) :

export default async function ProductPage({ params }: { params: Promise<{ id: string }> }) {
  const { id } = await params;
  // ...
}

Pourquoi c'est différent de Django / Flask / Express

Tu as l'habitude (côté Python) d'écrire un fichier urls.py qui mappe /products/<id> à une vue. En Next, le mapping vient gratuitement de l'arborescence — pas de table de routes à maintenir. Le revers : tu ne peux pas "voir" toutes les routes d'un coup, faut explorer les dossiers.

Piège classique

Pages vs Route handlers sont distincts :

  • page.tsx rend du HTML (UI) — accessible via navigateur
  • route.ts rend du JSON / autre (API) — accessible via fetch() ou curl

Si tu mets les deux dans le même dossier, Next refuse de builder. Sépare : pages sous app/..., APIs sous app/api/....

Dans ton code wari