Leçon 8 / 20

Charger une fiche de randonnée

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

Objectif : Récupérer une randonnée par son identifiant et distinguer un résultat absent d’une erreur technique.

Une adresse comme /randonnees/42 doit afficher la randonnée 42, pas la liste complète du catalogue. Pour obtenir une fiche fiable, vous devez extraire l’identifiant de l’adresse puis interroger votre API côté serveur. Vous devez aussi distinguer une randonnée inexistante d’une panne : ces deux situations ne doivent pas produire le même résultat.

Lire l’identifiant dans la route

Dans l’App Router, le dossier app/randonnees/[id] définit un segment dynamique : la partie de l’adresse qui remplace [id] est accessible dans les paramètres de la page. Dans les versions récentes de Next.js, params est une promesse ; vous la résolvez avec await avant d’utiliser l’identifiant. Vous avez déjà vu le rendu serveur et l’accès aux données dans les leçons précédentes ; ici, la page de détail conserve cette responsabilité côté serveur.

app/randonnees/[id]/page.tsxTexte
import { notFound } from 'next/navigation';

type Avis = {
  id: string;
  texte: string;
};

type Randonnee = {
  id: string;
  nom: string;
  description: string;
  difficulte: string;
  distance: number;
  avis: Avis[];
};

async function obtenirRandonnee(id: string): Promise<Randonnee | null> {
  const url = `${process.env.RANDONNEES_API_URL}/randonnees/${encodeURIComponent(id)}`;
  const reponse = await fetch(url, {
    next: { revalidate: 300 }
  });

  if (reponse.status === 404) {
    return null;
  }

  if (!reponse.ok) {
    throw new Error(`Échec du chargement de la randonnée (${reponse.status})`);
  }

  return reponse.json() as Promise<Randonnee>;
}

export default async function RandonneePage({
  params
}: {
  params: Promise<{ id: string }>;
}) {
  const { id } = await params;
  const randonnee = await obtenirRandonnee(id);

  if (!randonnee) {
    notFound();
  }

  return (
    <article className="rando-fiche">
      <h1 className="rando-titre">{randonnee.nom}</h1>
      <p>{randonnee.description}</p>
      <p>{randonnee.difficulte} · {randonnee.distance} km</p>
      <section className="rando-avis" aria-labelledby="titre-avis">
        <h2 id="titre-avis">Avis</h2>
        {randonnee.avis.length === 0 ? (
          <p className="rando-etat">Aucun avis pour le moment.</p>
        ) : randonnee.avis.map((avis) => (
          <p key={avis.id}>{avis.texte}</p>
        ))}
      </section>
    </article>
  );
}

La fonction construit l’adresse de l’API à partir de l’identifiant, encodé pour éviter qu’il ne modifie la structure de l’URL. RANDONNEES_API_URL doit être défini dans l’environnement serveur avec l’adresse de l’API déjà utilisée par votre projet ; ne préfixez pas cette variable par NEXT_PUBLIC_. Le résultat attendu est un objet JSON correspondant aux champs employés par la page, dont avis est un tableau, même lorsqu’il est vide.

Distinguer l’absence d’une erreur

Une réponse HTTP 404 signifie que l’identifiant ne correspond à aucune randonnée : la fonction retourne alors null. La page appelle notFound(), qui demande à Next.js d’afficher le traitement standard de ressource introuvable plutôt qu’une fiche vide. À l’inverse, une erreur réseau ou un statut HTTP autre que 404 provoque une exception ; elle ne doit pas être maquillée en absence de résultat.

Le paramètre next.revalidate garde ici la même durée de 300 secondes que la lecture du catalogue. Le cache peut donc réutiliser la réponse de la fiche pendant cette durée ; il ne change pas la distinction entre une réponse 404 et une erreur technique. La page rend les informations de la randonnée et ses avis directement sur le serveur, sans transmettre de secret au navigateur.

Vérifier le comportement

Ouvrez une adresse telle que /randonnees/42 avec un identifiant présent dans l’API : vous obtenez le nom, la description, la difficulté, la distance et les avis de cette randonnée. Testez ensuite un identifiant absent : la route signale une ressource introuvable. Enfin, provoquez une réponse 500 ou une indisponibilité de l’API ; cette fois, une erreur est levée au lieu d’afficher une fiche vide.

À retenir

  • Le dossier dynamique [id] fournit l’identifiant de la randonnée dans les paramètres de la page.
  • La page résout params, puis récupère l’enregistrement correspondant côté serveur.
  • Une réponse 404 devient une ressource introuvable avec notFound().
  • Les autres erreurs HTTP et les erreurs réseau restent des erreurs ; elles ne sont pas assimilées à une randonnée absente.
  • La lecture de la fiche conserve la durée de revalidation de 300 secondes.

Dans la prochaine leçon, vous ajouterez un état temporaire pendant le chargement d’une route.

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.