Next-Js
Junior
Quiz-Nextjs-Junior
Data-Fetching
Middleware
Route-Handlers
Server-Actions
Isr
Dynamic-Routes
Questions-Entretien-Nextjs-Junior
Qcm-Nextjs-Junior
React
Metadata
Front-End
📝
Entretien Next.js Junior : data fetching et middleware
20 questions Next.js niveau junior : data fetching, middleware, route handlers, server actions, ISR, dynamic routes et metadata pour réussir un entretien.
Banque de révision : les 30 questions corrigées
Voici l'intégralité des 30 questions de « Entretien Next.js Junior : data fetching et middleware », chacune avec sa bonne réponse et son explication. Le quiz interactif ci-dessus en tire une sélection aléatoire à chaque tentative — utilisez cette liste complète pour réviser.
Explication :
Le SSR (Server-Side Rendering) génère le HTML dynamiquement à chaque requête utilisateur. La SSG (Static Site Generation) génère le HTML une fois au build, et ce HTML statique est servi instantanément à tous les utilisateurs.
Utilisez la SSG pour les pages qui ne changent pas souvent (blog, documentation). Utilisez le SSR pour les pages avec des données utilisateur spécifiques (dashboard, profil).
Explication :
Par défaut,
fetch() dans un Server Component utilise le cache (cache: "force-cache"), ce qui rend la page statique (SSG). Pour du SSR (dynamique), il faut explicitement cache: "no-store".
Ajoutez
next: { revalidate: 3600 } pour de l'ISR : la page sera régénérée toutes les heures.
Explication :
L'ISR permet de régénérer des pages statiques périodiquement ou à la demande. On définit un intervalle de revalidation (
revalidate) après lequel la page sera mise à jour en arrière-plan.
Deux types d'ISR : par intervalle de temps (
next: { revalidate: 60 }) et on-demand avec revalidatePath() ou revalidateTag().
Explication :
Dans
route.js, on exporte export async function POST(request) { const body = await request.json(); ... return Response.json({ success: true }) }. L'API Web standard remplace req.body d'Express.
Pensez à gérer les erreurs avec try/catch et à retourner un statut approprié :
return Response.json({ error: "..." }, { status: 400 }).
Explication :
Les Server Actions (marquées
"use server") sont des fonctions exécutées côté serveur uniquement. Elles simplifient les mutations sans avoir à créer des API routes manuelles. Parfaites pour les formulaires.
Dans un formulaire :
<form action={maServerAction}>. La fonction reçoit automatiquement les FormData du formulaire.
Explication :
Le fichier
middleware.js (ou .ts) à la racine du projet permet d'intercepter toutes les requêtes entrantes. On peut rediriger, réécrire les URLs, vérifier l'authentification, ajouter des en-têtes.
Le Middleware s'exécute sur l'Edge Runtime par défaut. Utilisez
config.matcher pour limiter les routes concernées.
Explication :
"use client" transforme un composant en Client Component. À utiliser quand le composant a besoin d'interactivité (useState, onClick), d'API navigateur (localStorage, window), ou de hooks React.
Placez la directive le plus bas possible dans l'arbre des composants. Gardez la structure et les données côté serveur, isolez l'interactivité.
Explication :
Dans un Client Component, on utilise
useParams() importé de next/navigation. Dans un Server Component, les params sont directement passés en props.
Exemple Client :
const params = useParams(); const slug = params.slug;.
Explication :
La fonction
generateMetadata({ params, searchParams }) permet de générer des métadonnées dynamiques. Elle s'exécute côté serveur, peut fetch des données, et retourne un objet metadata.
Exemple :
export async function generateMetadata({ params }) { const post = await getPost(params.slug); return { title: post.title } }.
Explication :
L'option
next: { revalidate: n } (n en secondes) active l'ISR. La page est servie statiquement, puis régénérée en arrière-plan après n secondes quand une requête arrive.
Pour désactiver le cache et forcer le SSR :
fetch(url, { cache: "no-store" }).
Explication :
Le streaming envoie le HTML par morceaux. Les parties entourées de
<Suspense fallback={<Loader />}> affichent d'abord le fallback, puis le contenu réel est streamé et remplace le fallback quand il est prêt.
Utilisez
loading.js pour un Suspense automatique, ou <Suspense> manuellement pour un contrôle plus fin.
Explication :
Dans
next.config.js : async redirects() { return [{ source: "/ancienne", destination: "/nouvelle", permanent: true }] }. On peut aussi utiliser redirect() de next/navigation dans un Server Component.
Pour des redirections conditionnelles (auth), utilisez le Middleware ou
redirect() dans un Server Component.
Explication :
revalidatePath("/blog") régénère la page à cette route. revalidateTag("posts") invalide toutes les requêtes fetch qui ont été taguées avec fetch(url, { next: { tags: ["posts"] } }), quel que soit l'endroit où elles sont utilisées.
Utilisez les tags pour invalider des données partagées entre plusieurs pages (ex: mise à jour d'un article → invalider la liste et le détail).
Explication :
Dans un Server Component (page.js), les
searchParams sont passés en props. Dans un Client Component, on utilise useSearchParams() de next/navigation.
Attention :
useSearchParams() nécessite un Client Component ou un Suspense boundary.
Explication :
Next.js fait du code splitting automatique par route. Chaque page ne charge que le JavaScript nécessaire à son fonctionnement. On peut aussi utiliser
dynamic() pour du lazy loading de composants spécifiques.
Pour charger un composant lourd uniquement quand nécessaire :
const HeavyComponent = dynamic(() => import("./HeavyComponent")).
Explication :
Dans un Server Component, on utilise
cookies() importé de next/headers. C'est une fonction synchrone qui retourne l'objet cookies. Exemple : const cookieStore = cookies(); const token = cookieStore.get("token"). cookies() est une fonction dynamique : son utilisation rend toute la route dynamique (SSR).
Explication :
Dans un Server Component async, on peut utiliser
try/catch pour gérer les erreurs de fetch. Pour une gestion déclarative, le fichier error.js (Error Boundary) capture les erreurs non gérées.
Combinez les deux : try/catch pour des comportements spécifiques, error.js comme filet de sécurité global.
Explication :
Un Server Component peut fetch des données et les passer comme props à un Client Component enfant. Le Server Component s'exécute d'abord, puis les données sérialisées sont transmises au Client Component.
Les données passées doivent être sérialisables (pas de fonctions, pas de classes). Privilégiez les types simples : string, number, object, array.
Explication :
Le dossier
src/ (optionnel) permet de placer app/ (ou pages/) à l'intérieur, séparant le code source des fichiers de config racine (next.config.js, package.json, tsconfig.json).
Proposé lors du
create-next-app. Utile pour les grands projets avec beaucoup de fichiers de configuration.
Explication :
En production,
<Link> précharge automatiquement la route cible dès que le lien apparaît dans le viewport (intersection observer). Cela rend la navigation quasi-instantanée.
Pour désactiver ce comportement sur un lien spécifique :
<Link href="/route" prefetch={false}>.
Explication :
notFound() (importée de next/navigation) permet de déclencher programmatiquement la page 404. À utiliser dans un Server Component quand une ressource fetchée n'existe pas.
Pattern typique :
const post = await getPost(slug); if (!post) notFound();.
Explication :
La fonction
headers() dans next.config.js permet de définir des en-têtes HTTP personnalisés pour certaines routes. Exemple : ajouter des headers de sécurité (CSP, CORS, HSTS).
Exemple :
async headers() { return [{ source: "/(.*)", headers: [{ key: "X-Frame-Options", value: "DENY" }] }] }.
Explication :
Les Route Handlers (
route.js) créent des endpoints API RESTful standards accessibles via HTTP. Les Server Actions sont des fonctions appelées directement depuis des Client Components, sans créer de route API explicite.
Utilisez les Server Actions pour les formulaires et mutations internes. Utilisez les Route Handlers pour des API publiques, des webhooks, ou l'intégration avec des services tiers.
Explication :
next/dynamic permet de charger un composant uniquement quand il est nécessaire. Options : loading (composant de fallback), ssr: false (désactiver le SSR pour ce composant).
Utile pour les composants lourds (éditeurs, visualiseurs) ou les bibliothèques qui utilisent
window et ne fonctionnent pas côté serveur.
Explication :
L'approche recommandée : Middleware pour vérifier les sessions côté serveur, Server Actions pour les opérations login/logout (le token reste côté serveur), cookies httpOnly pour stocker les sessions. NextAuth.js/Auth.js simplifie tout cela.
Ne stockez jamais de tokens sensibles dans localStorage. Préférez les cookies httpOnly gérés par le serveur.
Explication :
Les Route Groups utilisent des dossiers nommés entre parenthèses :
app/(marketing)/page.js. Le nom entre parenthèses n'affecte pas l'URL. Utile pour organiser les routes sans modifier les chemins.
Utile pour appliquer différents layouts à des groupes de pages :
app/(marketing)/layout.js et app/(dashboard)/layout.js.
Explication :
Avec
Promise.all(), on lance plusieurs fetch simultanément : const [data1, data2] = await Promise.all([fetch(url1), fetch(url2)]). Évitez d'attendre chaque fetch séquentiellement.
Le séquentiel :
const a = await fetch1(); const b = await fetch2(); est plus lent. Préférez Promise.all quand les requêtes sont indépendantes.
Explication :
Depuis Next.js 14, les
params sont passés au layout.js en props. Exemple : export default function Layout({ params, children }) { return <div>Article {params.slug}{children}</div> }.
Utile pour afficher le titre de la page courante dans une barre de navigation ou un fil d'Ariane.
Explication :
Le composant
<Image> utilise les attributs width et height pour calculer le ratio et réserver l'espace dans le layout. Le fill avec sizes évite aussi le CLS.
Ajoutez toujours
width et height (ou utilisez fill avec un conteneur positionné) pour éviter le saut de mise en page.
Explication :
generateStaticParams() est utilisée dans les pages dynamiques pour définir quels paramètres doivent être pré-générés au build (SSG). Exemple : export async function generateStaticParams() { const posts = await getPosts(); return posts.map(p => ({ slug: p.slug })) }.
Si un paramètre n'est pas retourné par generateStaticParams, la page sera rendue en SSR (dynamique) à la première requête, puis mise en cache.