Aller au contenu principal
AnthemionAnthemion
Retour au blog

Démarrer avec Next.js 16

20 février 20265 min read
Next.jsReactTypeScript

Pourquoi Next.js

Quand j'ai commencé à coder, le choix du framework était un labyrinthe. React seul ? Vite ? Remix ? Après avoir testé plusieurs options, je suis resté sur Next.js pour une raison simple : il gère tout le pipeline — routing, rendu, optimisation, déploiement — sans que j'aie à assembler les pièces moi-même.

Next.js 16 est la version que j'utilise pour ce portfolio et pour RecettesApp. Voici ce que j'ai retenu.

Les changements qui comptent

Params asynchrones

C'est le changement le plus visible. Dans les pages dynamiques, params et searchParams sont désormais des Promises. Il faut les await :

// Avant (Next.js 15)
export default function Page({ params }: { params: { slug: string } }) {
  const post = getPost(params.slug);
}
 
// Maintenant (Next.js 16)
export default async function Page({
  params,
}: {
  params: Promise<{ slug: string }>;
}) {
  const { slug } = await params;
  const post = getPost(slug);
}

Pourquoi ce changement ? Next.js prépare le terrain pour le rendu partiel (Partial Prerendering). Les params asynchrones permettent au framework de commencer le rendu avant même que les paramètres soient résolus.

Tailwind CSS v4

Exit le fichier tailwind.config.ts. La configuration se fait directement dans le CSS :

@import "tailwindcss";
 
@theme inline {
  --color-primary: oklch(0.55 0.15 220);
  --color-accent: oklch(0.65 0.18 50);
  --font-sans: var(--font-geist-sans);
  --font-mono: var(--font-geist-mono);
}

C'est plus propre. Les variables CSS sont directement accessibles dans Tailwind (bg-primary, text-accent), et le tree-shaking est plus efficace.

Turbopack par défaut

Le dev server utilise Turbopack au lieu de Webpack. En pratique : le hot reload est quasi-instantané, même sur un projet avec beaucoup de fichiers. Sur mon portfolio (~50 fichiers), le démarrage prend environ 1 seconde.

Créer un projet

npx create-next-app@latest mon-app --typescript --tailwind --app --src-dir

Ce que ça génère :

  • src/app/ — les pages et layouts (App Router)
  • src/app/layout.tsx — le layout racine
  • src/app/page.tsx — la page d'accueil
  • CSS avec Tailwind v4 pré-configuré

La structure App Router

Le concept clé : chaque dossier dans app/ est une route.

src/app/
├── page.tsx           → /
├── about/page.tsx     → /about
├── blog/
│   ├── page.tsx       → /blog
│   └── [slug]/
│       └── page.tsx   → /blog/mon-article
└── layout.tsx         → Layout partagé

Les fichiers spéciaux :

  • page.tsx — le contenu de la route
  • layout.tsx — le wrapper qui persiste entre les navigations
  • loading.tsx — l'état de chargement
  • not-found.tsx — la page 404

Server Components vs Client Components

Par défaut, tout est Server Component — le code s'exécute côté serveur, pas dans le navigateur. C'est plus performant et ça permet d'accéder directement au filesystem ou à la base de données.

Tu ajoutes "use client" uniquement quand tu as besoin d'interactivité :

// Server Component (par défaut) — peut lire des fichiers, fetch des données
export default function BlogPage() {
  const posts = getAllPosts(); // Accès filesystem direct
  return <PostList posts={posts} />;
}
 
// Client Component — pour useState, useEffect, onClick, animations
"use client";
export function ThemeToggle() {
  const { theme, setTheme } = useTheme();
  return <button onClick={() => setTheme(theme === "dark" ? "light" : "dark")}>Toggle</button>;
}

La règle : commence toujours en Server Component. Ajoute "use client" seulement si le compilateur te le demande ou si tu as besoin de hooks React.

SSG : le site statique

Pour un blog ou un portfolio, le Static Site Generation est idéal. Les pages sont générées au build, pas à chaque requête.

// Génère toutes les pages au build
export function generateStaticParams() {
  const posts = getAllPosts();
  return posts.map((post) => ({ slug: post.slug }));
}
 
// Génère les métadonnées dynamiquement
export async function generateMetadata({ params }: Props) {
  const { slug } = await params;
  const post = getPostBySlug(slug);
  return { title: post.title, description: post.description };
}

Le résultat : des pages HTML pré-rendues, servies en quelques millisecondes. Pas de serveur, pas de base de données à l'exécution.

Le déploiement

Vercel déploie automatiquement à chaque push sur main. Le pipeline :

  1. git push → GitHub
  2. Vercel détecte le push, lance next build
  3. Les pages statiques sont distribuées sur le CDN
  4. Le site est en ligne en ~30 secondes

Pas de Docker, pas de serveur à gérer. Pour un site statique, c'est la solution la plus simple.

Ce que j'en retiens

Next.js 16 fait beaucoup de choses pour toi — et c'est à la fois sa force et son piège. La force : tu peux avoir un site en production en quelques heures. Le piège : si tu ne comprends pas ce qui se passe sous le capot (Server Components, hydration, build vs runtime), tu vas te retrouver à debugger des erreurs incompréhensibles.

Mon conseil : lis la documentation officielle, section par section. Pas en diagonale.