Leçon 1 / 20

Repérer les composants serveur dans l’App Router

8 min Next.js — données, formulaires et cache Gratuit

Objectif : Identifier les composants exécutés sur le serveur dans une route de catalogue.

Quand vous affichez un catalogue, vous devez récupérer ses données sans exposer au navigateur les accès à la base. Dans l’App Router de Next.js, les composants de page sont exécutés côté serveur par défaut : vous pouvez donc y préparer le contenu avant son affichage.

Dans cette leçon, vous repérez cette frontière dans la route du catalogue de randonnées. Vous verrez le rôle du serveur et celui du navigateur, sans encore traiter les filtres, la mise en cache ou la configuration des accès aux données.

Une page de l’App Router est serveur par défaut

Un fichier app/page.tsx définit le contenu de la route d’accueil. Dans l’App Router, ce composant est un composant serveur tant que vous ne lui indiquez pas explicitement un comportement différent. Il n’est donc pas nécessaire d’ajouter une directive pour qu’il s’exécute sur le serveur.

Le layout racine du projet est lui aussi rendu côté serveur. Il fournit la structure partagée des routes et importe l’unique feuille de style prévue par le projet. La page catalogue fournit ensuite son propre contenu à l’intérieur de cette structure, sans remplacer le layout.

app/layout.tsxTexte
import './style.css';

export default function RootLayout({ children }) {
  return (
    <html lang="fr">
      <body>
        <div className="rando-page">
          <header className="rando-entete">
            <a className="rando-marque" href="/">Catalogue de randonnées</a>
            <nav className="rando-navigation" aria-label="Navigation principale">
              <a href="/">Toutes les randonnées</a>
            </nav>
          </header>
          <main className="rando-contenu">{children}</main>
        </div>
      </body>
    </html>
  );
}

Le composant serveur prépare le catalogue

Une page peut être déclarée avec async et attendre les données avant de construire son résultat. Ici, obtenirRandonnées représente l’accès au catalogue déjà prévu dans le squelette du projet. Cette leçon ne détaille pas sa mise en œuvre : vous apprendrez à organiser cet accès dans la leçon consacrée à la couche de données.

app/page.tsxTexte
export default async function CataloguePage({ searchParams }) {
  const { difficulte } = await searchParams;
  const randonnees = await obtenirRandonnées({ difficulte });

  return (
    <>
      <h1 className="rando-titre">Randonnées à découvrir</h1>
      <form className="rando-recherche" action="/">
        <label htmlFor="difficulte">Difficulté</label>
        <select id="difficulte" name="difficulte" defaultValue={difficulte ?? ''}>
          <option value="">Toutes</option>
          <option value="facile">Facile</option>
          <option value="intermediaire">Intermédiaire</option>
          <option value="difficile">Difficile</option>
        </select>
        <button className="rando-bouton" type="submit">Rechercher</button>
      </form>
      {randonnees.length === 0 ? (
        <p className="rando-etat" role="status">
          Aucune randonnée ne correspond à cette recherche.
        </p>
      ) : (
        <ul className="rando-liste">
          {randonnees.map((randonnee) => (
            <li className="rando-carte" key={randonnee.id}>
              <a href={`/randonnees/${randonnee.id}`}>
                <h2>{randonnee.nom}</h2>
                <p>{randonnee.difficulte} · {randonnee.distance} km</p>
              </a>
            </li>
          ))}
        </ul>
      )}
    </>
  );
}

Le composant attend les données, puis produit des éléments d’interface à partir de chaque randonnée. Le résultat est transmis au navigateur pour affichage, mais le code de ce composant et l’appel au catalogue s’exécutent côté serveur. Le navigateur reçoit donc la page à présenter ; il n’effectue pas lui-même l’accès aux données du catalogue.

Suivre le parcours des données

Dans cette page, le parcours est direct : le composant de route demande les randonnées, attend le résultat, puis construit une liste ou un message indiquant l’absence de résultats. Cette organisation permet de garder le chargement des données à l’endroit où la route en a besoin. Elle respecte aussi la convention du projet : l’accès à la base reste exclusivement côté serveur.

Le formulaire de recherche est rendu dans la même page, mais sa présence dans le HTML ne transforme pas le composant en composant client. Ici, il soumet ses valeurs vers la route ; vous étudierez plus tard comment délimiter les interactions qui nécessitent du code exécuté dans le navigateur. De même, les paramètres de recherche et leur validation seront traités dans une leçon dédiée.

À retenir

  • Dans l’App Router, les pages sont des composants serveur par défaut.
  • Une page serveur peut attendre les données avant de produire son interface.
  • L’accès au catalogue reste côté serveur, conformément au contrat du projet.
  • Le HTML affiché dans le navigateur ne signifie pas que le code de la page s’y est exécuté.

Dans la prochaine leçon, vous délimiterez les composants client pour les interactions qui nécessitent un état dans le navigateur.

Envie d'aller plus loin ?

Les cours Enovatic sont gratuits et le resteront. Si vous cherchez un accompagnement encadré, nos formations professionnelles sont animées par les mêmes formateurs.