Introduction aux Stratégies de Données et de Rendu
1. getStaticPaths : Génération des Chemins Statiquees Dynamiques
Cette fonction est essentielle pour définir les chemins dynamiques qui doivent être pré-rendus au moment de la construction pour une application SSG.
// Exemple: pages/blog/[articleId].js
export async function getStaticPaths() {
return {
paths: [
// 1. Format de paramètre basique: pages/blog/[articleId].js → blog/premier-article
{ params: { articleId: 'premier-article' } },
// 2. Routage dynamique imbriquée: pages/[category]/[slug].js → technologies/nextjs-guide
{ params: { category: 'technologies', slug: 'nextjs-guide' } },
// 3. Chemin générique facultatif (catch-all): pages/[...pathSegments].js → docs/library/api
{ params: { pathSegments: ['docs', 'library', 'api'] } },
],
// Option de repli (fallback), obligatoire parmi les trois suivantes :
fallback: false, // Option 1: Seuls les chemins listés sont générés, les autres mènent à une 404.
fallback: true, // Option 2: Permet la génération incrémentale, affiche un état de chargement.
fallback: 'blocking' // Option 3: Génération incrémentale, bloque la requête jusqu'à ce que la page soit prête.
};
}
Détails des paramètres : Le contexte d'entrée est généralement vide, mais peut inclure des informations de localisation telles que locales (liste des langues supportées) et defaultLocale (langue par défaut), bien que moins utilisées dans le Pages Router.
2. getStaticProps : Récupération des Propriétés de Page pour SSG
Utilisée pour acquérir les données nécessaires à une page lors de la phase de compilation.
export async function getStaticProps(fetchContext) {
// fetchContext.params contient les paramètres de routage dynamique.
const { params } = fetchContext;
// Simulation de récupération de données pour un article spécifique
const articleData = { id: params.articleId, title: 'Titre de l\'article' };
return {
props: {
// Les données sont injectées dans le composant de la page.
data: articleData,
},
revalidate: 120, // Clé de l'ISR (Incremental Static Regeneration) : revalidation après 120 secondes.
notFound: false, // Si défini à true, renvoie une page 404.
redirect: {
destination: '/nouvelle-destination',
permanent: false, // true pour 308 (permanent), false pour 307 (temporaire).
}
};
}
Caractéristiques clés :
- Un seul parmi
props,notFound, ouredirectdoit être retourné. - Le paramètre
revalidateest crucial pour l'ISR. - Pour le SEO, utilisez
permanent: true(code 308) pour les redirections définitives etpermanent: false(code 307) pour les temporaires. - Une page
notFoundpersonnalisée offre une meilleure expérience utilisateur qu'une erreur générique.
3. getServerSideProps : Récupération des Données en Temps Réel pour SSR
Cette fonction récupère les données les plus récentes à chaque requête entrante.
export async function getServerSideProps({ request, response, urlParams, queryParams, currentLocale }) {
// Description des paramètres :
// request → Objet de requête HTTP (inclut cookies, en-têtes, etc.)
// response → Objet de réponse HTTP (permet de définir en-têtes, cookies, etc.)
// urlParams.articleId → Issu de l'URL : /articles/unique-id-123
// queryParams → Issu des paramètres de requête URL : /articles?format=json
// currentLocale → Déduit de l'en-tête Accept-Language ou de l'URL
// Exemple de récupération de données dynamique basée sur la requête
const dynamicContent = await fetch(`https://api.example.com/data?id=${urlParams.articleId}`);
const jsonData = await dynamicContent.json();
return {
props: {
// Les données sont injectées dans le composant de la page.
serverData: jsonData,
}
// Note : Le paramètre 'revalidate' n'est pas disponible ici.
};
}
Comparaison des Stratégies de Rendu
| Stratégie | Indicateur Clé | Cas d'Usage Recommandé |
|---|---|---|
| SSG | getStaticProps() sans revalidate |
Pages avec contenu statique ou peu changeant (ex: documentation, blog post classique) |
| ISR | getStaticProps() + revalidate |
Contenu mis à jour fréquemment mais non en temps réel (ex: actualités, fiches produit) |
| SSR | getServerSideProps() |
Contenu personnalisé ou données nécessitant une fraîcheur absolue à chaque requête (ex: tableaux de bord utilisateur, résultats de recherche) |
| CSR | useEffect() / useSWR() côté client |
Données fortement interactives ou spécifiques à l'utilisateur après le chargement initial de la page (ex: filtres, recherche instantanée) |
Les approches SSG et SSR génèrent une HTML complète côté serveur, nécessitant une étape d'hydratation côté client pour devenir interactives. Par contraste, l'import dynamique de composants avec dynamic de Next.js permet à React de rendre d'abord un élément de substitution (loading) et de remplacer ensuite ce contenu par le composant réel une fois son bundle JS téléchargé, ce qui est plus proche d'une approche CSR sans hydratation.
Import Dynamique et Segmentation du Code
import dynamic from 'next/dynamic';
const DynamicContentModule = dynamic(
() => import('../components/HeavyComponent'),
{
ssr: true, // Valeur par défaut : le composant est chargé côté serveur.
loading: () => <p>Chargement du module...</p>
}
);
Fonctionnalités essentielles :
- Le paramètre
ssrest par défaut àtrue, ce qui signifie que le composant est pré-rendu sur le serveur. - L'objectif principal est la segmentation du code (code splitting) : les composants importés via
dynamicsont regroupés dans des bundles JS distincts, chargés uniquement quand nécessaire. - Contrairement à un
importclassique, qui inclut le composant dans le bundle principal,dynamicpermet un chargement à la demande, améliorant les performances initiales. - Le rendu initial affiche un indicateur de chargement (
loading) avant que le composant réel ne soit monté, similaire à une stratégie CSR où l'interactivité est immédiate sans phase d'hydratation.
Fonctionnalités d'Optimisation Intégrées
1. Optimisation des Images
- Next.js offre une optimisation automatique (redimensionnement, formatage, chargement paresseux) via le composant
Image. - Supporte des formats modernes comme WebP.
- Aide à prévenir les décalages de mise en page (CLS).
2. Optimisation des Polices
- Optimisation et préchargement automatiques des polices.
- Réduit également le CLS.
3. Optimisation des Scripts
- Permet d'optimiser le chargement de scripts tiers.
- Supporte l'attribut
strategy(beforeInteractive,afterInteractive,lazyOnload) pour contrôler le moment du chargement.
Le Système de Routage
1. Le Routage par Fichiers (Pages Router)
- Un système de routage basé sur la structure des fichiers du répertoire
pages/. - Prend en charge les routes dynamiques :
[id].js,[...slug].js. - Permet le routage imbriqué via des sous-dossiers.
2. Le Routage Superficiel (Shallow Routing)
import { useRouter } from 'next/router';
const MyComponent = () => {
const navigationController = useRouter();
const navigateWithShallow = () => {
navigationController.push(
'/products?category=electronics&page=2',
undefined,
{ shallow: true } // Le paramètre clé
);
};
// ...
};
Scénarios d'utilisation : Filtrage, tri, pagination, changement d'onglet, où seule l'URL doit être mise à jour sans recharger la page.
- Navigation classique : Modification de l'URL → nouvelle récupération de données → nouveau rendu du composant.
- Navigation superficielle : Modification de l'URL → mise à jour directe de l'URL → maintien de l'état actuel du composant.
Le routage superficiel est idéal pour les situations où seuls les paramètres de requête changent et le contenu de la page peut être mis à jour par la logique côté client. Cette fonctionnalité est moins courante avec l'adoption progressive du App Router.
3. Les Routes d'API
- Tout fichier placé dans le répertoire
pages/api/agit comme un point d'accès API côté serveur. - Ces fonctions reçoivent des objets
req(requête) etres(réponse) pour gérer les échanges. - Cette fonctionnalité transforme Next.js d'un simple framework frontal en une solution full-stack complète.
4. Les Middlewares
- Historiquement, les middlewares étaient définis dans un fichier
_middleware.jsau sein du répertoirepages/. - La pratique recommandée actuelle est de créer un fichier
middleware.jsà la racine du projet.
L'App Router (Approche Moderne)
L'App Router représente la solution la plus récente et recommandée pour Next.js, offrant des avantages significatifs en termes de performance, notamment via l'hydratation sélective. Seuls les composants marqués avec 'use client' sont hydratés.
1. Simplification de la Récupération de Données
getStaticPropsest remplacé par l'utilisation directe de fonctions asynchrones dans les composants (par défaut SSG avec cache).getStaticPathsest remplacé pargenerateStaticParams.
export async function generateStaticParams() {
return [{ slug: 'premier-produit' }, { slug: 'second-produit' }];
}
export const dynamicParams = true; // Équivalent à fallback: true
- L'équivalent de
getServerSidePropsest obtenu en :
import { unstable_noStore } from 'next/cache';
export const dynamic = 'force-dynamic'; // Force le rendu dynamique à chaque requête.
// Alternativement, utiliser l'option cache: 'no-store' sur les requêtes fetch.
// Ou déclencher un rendu dynamique avec des fonctions comme cookies() ou headers().
2. API de Métadonnées
- La fonction
generateMetadatapermet de générer dynamiquement des métadonnées pour un SEO amélioré.
3. Implémentation d'ISR
export const revalidate = 90; // La page sera revalidée toutes les 90 secondes.
// Ou, pour une requête fetch spécifique :
fetch(url, { next: { revalidate: 90 } });
4. Composants Client
- Nécessitent la directive explicite
'use client'au début du fichier. - L'App Router effectue une hydratation partielle par défaut : les composants serveur ne sont pas hydratés, seuls les composants client le sont.
Conditions d'hydratation :
- Le composant est marqué
'use client'(indiquant qu'il requiert de l'interactivité). - Le composant a été pré-rendu en HTML côté serveur (par défaut ou si
ssr: truepour les imports dynamiques).
Cas sans hydratation :
- Composants Serveur (sans
'use client'). - Composants Client avec
ssr: falsedans un import dynamique. - Composants purement CSR (aucun rendu initial côté serveur).
5. Optimisation de l'Import Dynamique
dynamic(() => import('../components/LargeClientComponent'), { ssr: false }) // Utilisé principalement pour un chargement différé.
6. Rendu en Streaming
- L'App Router prend en charge nativement le rendu en streaming.
- Nécessite l'utilisation du composant
<Suspense>pour encapsuler le contenu asynchrone. - Chaque limite de
<Suspense>permet un streaming indépendant.
7. Server Actions
- Fonctions déclarées avec la directive
'use server'. - Elles encapsulent une communication réseau, offrant une expérience de "fonction locale" pour les appels côté serveur.
- Simplifient le traitement des formulaires et réduisent la nécessité de créer des routes API complexes pour des opérations simples.
8. Autres Fonctionnalités Clés
-
Middleware : Défini dans
middleware.jsà la racine du projet, pour l'authentification, l'internationalisation, les redirections, etc. -
Groupes de Routes : Utilisation de parenthèses
( )autour des noms de dossiers pour organiser la structure de fichiers sans impacter l'URL. -
Cookies/Headers : Accès aux informations de requête via les fonctions
cookies()etheaders()dans les composants serveur. -
Routes Interceptrices : Utilisation du préfixe
(.)pour intercepter une route dans le même répertoire, souvent pour afficher des modales. -
Navigation Côté Client :
usePathname: Récupère le chemin URL actuel.useSearchParams: Accède aux paramètres de requête URL.useRouter: Permet de manipuler la navigation.
Note : Ces hooks doivent être utilisés dans des composants client (
'use client') etusePathname/useSearchParamspeuvent déclencher un rendu dynamique.
Synthèse et Recommandations
Conseils de Développement
- Composants interactifs : Utilisez
'use client'. - Composants à chargement différé : Employez
dynamic. - Contenu à mise à jour régulière : Configurez
revalidate. - Gestion simplifiée des données côté client : Considérez
useSWR.
Choix de la Stratégie de Rendu
- Pages statiques simples : Adoptez le SSG par défaut de l'App Router.
- Données en temps réel : Utilisez
dynamic = 'force-dynamic'ouunstable\_noStore(). - Contenu mis à jour fréquemment : Implémentez l'ISR (
revalidate). - Données fortement interactives côté utilisateur : Privilégiez le CSR (
useEffect/useSWR).