Définir le layout partagé
Objectif : Afficher un en-tête et un pied de page communs sur l’accueil et les pages de détail, tout en conservant le contenu propre à chaque route.
Quand vous passez de l’accueil à une page de détail, l’identité du catalogue doit rester visible et cohérente. Si vous répétez l’en-tête dans chaque page, vous dupliquez du code et risquez de faire diverger les versions.
Vous allez donc placer la structure commune dans le layout racine, puis laisser chaque page fournir uniquement son contenu principal. Les routes et les pages déjà créées restent inchangées ; leur rendu vient s’insérer dans cette structure.
Le layout racine du catalogue
Dans l’App Router, le layout racine est défini dans `app/layout.tsx`. Il encadre les pages de l’application : l’élément `children` représente le contenu de la route courante, qu’il s’agisse de `app/page.tsx` ou de `app/itineraires/[slug]/page.tsx`.
Le layout retourne aussi les éléments HTML qui entourent ce contenu. Ici, l’en-tête contient la marque et une navigation minimale, tandis que le pied de page ferme la structure. Le composant `Link` est utilisé pour respecter le squelette du projet ; son fonctionnement et la navigation associée seront étudiés dans la prochaine leçon.
import Link from "next/link";
import "../style.css";
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="fr">
<body className="sentier-page">
<header className="sentier-entete">
<Link className="sentier-marque" href="/">
Sentiers
</Link>
<nav className="sentier-navigation" aria-label="Navigation principale">
<Link className="sentier-lien" href="/">
Accueil
</Link>
</nav>
</header>
<main className="sentier-contenu">{children}</main>
<footer className="sentier-pied">Catalogue de randonnées</footer>
</body>
</html>
);
}La propriété `children` est transmise par Next.js lorsque le layout enveloppe une route. En la plaçant dans ``, vous conservez un emplacement unique pour le contenu variable ; l’en-tête et le pied de page, eux, restent identiques sur les routes couvertes par ce layout.
Charger les styles communs
Le contrat du projet prévoit une feuille unique nommée `style.css`, placée à la racine. Depuis `app/layout.tsx`, l’import `../style.css` remonte d’un niveau pour atteindre ce fichier. L’import dans le layout rend les règles disponibles à l’ensemble des routes ; ne créez pas un second import dans les pages.
:root {
--sentier-couleur-texte: #20332b;
--sentier-couleur-fond: #f5f7f2;
--sentier-couleur-accent: #26734d;
--sentier-couleur-carte: #ffffff;
--sentier-espace: 1rem;
--sentier-espace-large: 2rem;
--sentier-rayon: 0.75rem;
--sentier-police: Arial, sans-serif;
}
.sentier-page {
min-height: 100vh;
margin: 0;
background: var(--sentier-couleur-fond);
color: var(--sentier-couleur-texte);
font-family: var(--sentier-police);
}
.sentier-entete {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--sentier-espace);
padding: var(--sentier-espace-large);
background: var(--sentier-couleur-carte);
}
.sentier-marque,
.sentier-lien,
.sentier-retour {
color: var(--sentier-couleur-accent);
}
.sentier-marque {
font-weight: bold;
}
.sentier-navigation {
display: flex;
gap: var(--sentier-espace);
}
.sentier-contenu {
width: min(100% - var(--sentier-espace-large), 72rem);
margin: 0 auto;
padding: var(--sentier-espace-large) 0;
}
.sentier-pied {
padding: var(--sentier-espace-large);
text-align: center;
}Aperçu appliqué au document HTML de cette leçon : la règle CSS est injectée dans la page pour voir son effet réel.
Les règles ci-dessus donnent une présentation de base à la structure partagée et définissent les variables autorisées du projet. Les classes appliquées au layout correspondent toutes au contrat ; les pages pourront continuer à utiliser leurs classes dédiées sans que vous changiez leur JSX. Si `style.css` contient déjà des règles, conservez-les et intégrez les règles nécessaires sans dupliquer les déclarations de variables.
Vérifier le rendu partagé
Enregistrez les deux fichiers et consultez l’accueil, puis une route de détail connue, par exemple `/itineraires/foret`. Dans les deux cas, vous devez retrouver la marque « Sentiers », la navigation « Accueil » et le pied de page « Catalogue de randonnées », autour du contenu propre à la page.
Le même layout racine encadre également les autres routes de l’application, y compris l’interface d’itinéraire introuvable déjà créée. Vous obtenez ainsi une structure constante sans recopier ces éléments dans les fichiers de page. À ce stade, les liens visibles sont en place ; leur comportement de navigation sera détaillé dans la prochaine leçon.
À retenir
- `app/layout.tsx` définit la structure commune autour des routes de l’application.
- `children` reçoit le contenu de la page courante et s’insère dans la zone principale.
- L’en-tête et le pied de page sont déclarés une seule fois dans le layout.
- La feuille `style.css` est importée depuis le layout racine et utilise les classes et variables autorisées.
Dans la prochaine leçon, vous étudierez le composant `Link` et la navigation entre les pages du catalogue.