Leçon 8 / 15

Créer des états de chargement utiles

15 min Next.js — performance, SEO et mise en production Gratuit

Objectif : Fournir un état de chargement stable pour la liste des randonnées.

Quand le détail d’un itinéraire attend ses données, une page vide ou un message sans dimensions réservées peut donner l’impression que le site est bloqué. À l’inverse, un état de chargement bien placé confirme que la navigation a commencé et limite les déplacements visuels à l’arrivée du contenu.

Vous allez compléter la route `/randonnees/[slug]` avec la convention `loading.tsx` de Next.js. La leçon précédente a déjà posé une frontière Suspense autour du détail asynchrone ; ici, vous donnez à l’état de repli une forme et une sémantique adaptées.

Créer le fichier de chargement à l’emplacement attendu

Dans l’App Router, un fichier `loading.tsx` placé dans un segment fournit automatiquement l’interface affichée pendant le chargement de ce segment. Le contrat du projet nomme ce fichier `chargement.tsx` : conservez ce nom dans l’arborescence existante et importez-le explicitement dans la page pour le fournir comme contenu de repli à la frontière Suspense.

Le squelette doit annoncer l’attente sans prétendre contenir déjà l’itinéraire. Réutilisez la classe contractuelle `rando-squelette` et indiquez un état de statut compréhensible par les technologies d’assistance. Ne créez pas de classes supplémentaires et ne placez pas de style directement dans le JSX.

app/randonnees/[slug]/chargement.tsxTexte
export default function ChargementItineraire() {
  return (
    <div className="rando-squelette" role="status" aria-live="polite">
      Chargement des détails de l’itinéraire…
    </div>
  );
}

Raccorder l’état de chargement à la route

Le fichier de chargement doit rester un composant léger et sans dépendance aux données d’un slug particulier. La page dynamique conserve la génération des métadonnées, la validation de l’itinéraire et le JSON-LD déjà mis en place ; seul le contenu de repli est partagé avec la frontière qui entoure le rendu asynchrone.

Extrait d’intégration dans app/randonnees/[slug]/page.tsxTexte
import { Suspense } from "react";
import ChargementItineraire from "./chargement";
import Itineraire from "./itineraire";

// Dans le JSX de la page, après la récupération et la validation
// de l’itinéraire et la préparation de ses données structurées :
<Suspense fallback={<ChargementItineraire />}>
  <Itineraire slug={slug} />
</Suspense>

Cet extrait montre le raccordement à conserver dans la page existante ; il ne remplace pas son fichier complet. Gardez les signatures, propriétés et exports présents dans votre projet, notamment ceux utilisés pour construire les métadonnées et les données structurées. La frontière doit entourer précisément la partie qui peut attendre, pas les éléments qui sont déjà disponibles.

Réserver l’espace pour éviter les sauts visuels

Un squelette qui ne fait que remplacer le contenu par une ligne de texte ne réserve presque aucun espace : lorsque le détail arrive, le reste de la page peut être repoussé. Donnez à `.rando-squelette` une hauteur minimale correspondant à la zone de détail et gardez cette règle dans `app/style.css`, seule feuille de style du projet. Ajustez cette hauteur d’après le contenu réel et vérifiez le résultat sur un écran étroit comme sur un écran large.

Vérifier les états de la route

Lancez l’application et ouvrez `/randonnees/cretes-du-jura`. Pour observer le repli, utilisez un environnement où la résolution du détail prend assez de temps, par exemple en ralentissant le réseau dans les outils du navigateur. Le squelette doit être annoncé comme un statut pendant l’attente, puis laisser place à l’itinéraire ; sur un slug inconnu, le traitement prévu par la page doit toujours aboutir à la réponse de route inconnue plutôt qu’à un chargement permanent.

Comparez la disposition pendant l’attente et après l’affichage du détail, puis contrôlez que le message n’est pas dupliqué lorsque l’interface de chargement automatique du segment est aussi présente. Si l’état n’apparaît jamais, l’opération attendue ne suspend peut-être pas réellement : la frontière ne remplace pas une attente absente. La prochaine leçon portera sur l’observation de la diffusion de la réponse dans le navigateur.

À retenir

  • Le fichier de chargement de ce projet est `app/randonnees/[slug]/chargement.tsx` ; il fournit un composant de repli léger.
  • La frontière Suspense existante reçoit ce composant comme fallback sans supprimer les métadonnées, le JSON-LD ni la gestion des slugs inconnus.
  • La classe `rando-squelette` porte l’état visuel et doit réserver, dans la feuille de style unique, un espace cohérent avec le détail final.
  • Vérifiez l’attente réelle, l’absence de message dupliqué et la stabilité de la disposition avant et après l’arrivée des données.

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.