Le modèle de rendu de Next.js 16
Dans Next.js 16, chaque composant React est soit un Server Component soit un Client Component. Par défaut, tout est Server Component. Vous devez explicitement opter pour le rendu client avec la directive "use client".
'use client'
✅ useState, useEffect, hooks React
✅ onClick, onChange, événements DOM
✅ Accès au navigateur (window, localStorage)
❌ Pas d'accès direct à la DB
❌ Bundle JS envoyé au client// Pas de directive nécessaire
✅ Lecture directe en base de données
✅ Accès au filesystem, variables secrètes
✅ Zéro JS envoyé au client
❌ Pas de hooks React (useState...)
❌ Pas d'événements DOMServer Component : fetcher des données directement
Un Server Component peut lire une base de données, un fichier, ou appeler une API directement dans le composant, sans useEffect ni useState. Le HTML généré est envoyé tel quel au navigateur — aucun JS React n’est envoyé pour ce composant.
// Pas de "use client" → Server Component par défaut
async function getPosts() {
const res = await fetch('https://api.example.com/posts');
return res.json();
}
export default async function BlogPage() {
// await directement dans le composant — aucun useEffect !
const posts = await getPosts();
return (
<ul className="space-y-4">
{posts.map((post: { id: number; title: string }) => (
<li key={post.id} className="p-4 border rounded-xl">
{post.title}
</li>
))}
</ul>
);
}
C’est la grande force des Server Components : le composant peut être async. Plus de useEffect(() => { fetch()... }, []) — vous écrivez du code asynchrone simple, comme dans n’importe quelle fonction Node.js.
Client Component : interactivité
Dès que vous avez besoin de useState, useEffect, d’événements comme onClick, ou d’accès au navigateur, ajoutez "use client" en haut du fichier.
'use client';
import { useState } from 'react';
export default function Counter() {
const [count, setCount] = useState(0);
return (
<div className="flex items-center gap-4">
<button
onClick={() => setCount(c => c - 1)}
className="w-10 h-10 rounded-full bg-gray-200 font-bold hover:bg-gray-300"
>−</button>
<span className="text-2xl font-mono w-12 text-center">{count}</span>
<button
onClick={() => setCount(c => c + 1)}
className="w-10 h-10 rounded-full bg-gray-900 text-white font-bold hover:bg-gray-700"
>+</button>
</div>
);
}
La règle clé : la frontière client
"use client" définit une frontière. Tout composant importé par un Client Component devient automatiquement client lui aussi. En revanche, un Server Component peut passer un Client Component en tant qu’enfant via children sans le « contaminer ».
// ✅ BON : Server Component qui compose un Client Component
// app/blog/page.tsx (Server Component)
import LikeButton from '@/components/LikeButton'; // Client
export default async function Post() {
const post = await fetchPost(); // côté serveur
return (
<article>
<h1>{post.title}</h1>
<p>{post.content}</p>
{/* Seul ce bouton est rendu côté client */}
<LikeButton postId={post.id} />
</article>
);
}
Une erreur courante est d’ajouter "use client" à tous les composants « par sécurité ». Cela annule tous les bénéfices des Server Components : le JS est envoyé au client, les données ne peuvent plus être fetchées côté serveur. N’ajoutez "use client" que là où c’est vraiment nécessaire.
Quand utiliser quoi ?
Besoin de useState / useEffect ? → "use client"
Besoin de onClick, onChange ? → "use client"
Besoin de window, localStorage ? → "use client"
Besoin d'une lib client (framer-motion...) ? → "use client"
Besoin de fetch / base de données ? → Server Component
Composant statique / pas d'interactivité ? → Server Component
Accès à des variables d'env secrètes ? → Server Component
Pas sûr ? → Server Component (défaut)
Exercice pratique
- Créez un Server Component
app/users/page.tsxqui fetchehttps://jsonplaceholder.typicode.com/userset affiche la liste des noms - Créez un Client Component
SearchBar.tsxavec unuseStatepour filtrer la liste - Passez la liste depuis le Server Component au Client Component via les props
- Ouvrez les DevTools → Network : observez qu’aucun fichier JS n’est envoyé pour le Server Component