Routeur App Router de Next.js
S'applique à Next.js 14+ avec le répertoire app/ et TypeScript.
Conventions de fichiers
app/layout.tsx— layout racine obligatoire. Doit inclure<html>et<body>.app/page.tsx— point d'entrée d'une route. Par défaut, c'est un composant serveur React (RSC).app/loading.tsx— fallback de streaming pour le segment.app/error.tsx— doit être un composant client ('use client'), reçoit{ error, reset }.app/not-found.tsx— interface utilisateur 404.app/route.ts— gestionnaire de route (API). ExporterGET,POST, etc.- Dynamique :
app/blog/[slug]/page.tsxreçoit{ params: { slug: string } }. - Groupes :
app/(marketing)/about/page.tsx— l'URL n'est pas affectée. - Parallèles :
app/@modal/page.tsx+layout({ modal }). Interception :app/(.)photo/[id]/page.tsx.
Règles
- Composants serveur par défaut. Ajouter
'use client'uniquement lorsque vous avez besoin de hooks, d'événements ou d'API navigateur. Garder les limites client petites — les repousser vers les feuilles. paramsetsearchParamssont asynchrones dans Next 15 :await params.- Ne jamais importer un composant serveur directement dans un composant client s'il utilise des fonctionnalités exclusives au serveur — le passer en tant que
children/propsà la place. - Utiliser
next/linkpour la navigation,next/navigation(useRouter,usePathname) uniquement dans les composants clients. Utiliserredirect()/notFound()depuisnext/navigationdans les composants serveur. - Colocaliser :
page.tsx,loading.tsx,error.tsxpar segment. Placer l'interface partagée danscomponents/, pas dansapp/sauf si routée.
Motifs
// app/blog/[slug]/page.tsx — params asynchrones Next 15
type Props = { params: Promise<{ slug: string }> };
export default async function BlogPost({ params }: Props) {
const { slug } = await params;
const post = await getPost(slug);
if (!post) notFound();
return <article>{post.title}</article>;
}
export async function generateStaticParams() {
const slugs = await getAllSlugs();
return slugs.map((slug) => ({ slug }));
}
// app/error.tsx — doit être un composant client
'use client';
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return (
<div>
<h2>Quelque chose s'est mal passé</h2>
<button onClick={() => reset()}>Réessayer</button>
</div>
);
}
// app/layout.tsx
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="fr">
<body>{children}</body>
</html>
);
}
Checklist
- Le nom du fichier et le placement dans le segment sont-ils corrects ?
- La directive client est-elle utilisée uniquement là où c'est nécessaire ?
-
loading.tsx/error.tsxsont-ils présents pour les segments asynchrones ? -
generateStaticParams+generateMetadatasont-ils utilisés lorsque le référencement est important ? - Aucun
useRouterprovenant denext/router(import du routeur pages-router) ?