Introduction/Guides/ISR

Comment implémenter la régénération statique incrémentielle (ISR)

Exemples

La régénération statique incrémentielle (ISR) vous permet de :

  • Mettre à jour du contenu statique sans reconstruire tout le site
  • Réduire la charge du serveur en servant des pages statiques pré-rendues pour la plupart des requêtes
  • Garantir que les en-têtes cache-control appropriés sont automatiquement ajoutés aux pages
  • Gérer un grand nombre de pages de contenu sans temps de construction next build longs

Voici un exemple minimal :

interface Post {
  id: string
  title: string
  content: string
}

// Next.js invalidera le cache lorsqu'une
// requête arrive, au maximum une fois toutes les 60 secondes.
export const revalidate = 60

// Nous pré-rendrons uniquement les paramètres de `generateStaticParams` au moment de la construction.
// Si une requête arrive pour un chemin qui n'a pas été généré,
// Next.js rendra la page côté serveur à la demande.
export const dynamicParams = true // ou false, pour renvoyer une 404 sur les chemins inconnus

export async function generateStaticParams() {
  const posts: Post[] = await fetch('https://api.vercel.app/blog').then((res) =>
    res.json()
  )
  return posts.map((post) => ({
    id: String(post.id),
  }))
}

export default async function Page({
  params,
}: {
  params: Promise<{ id: string }>
}) {
  const { id } = await params
  const post: Post = await fetch(`https://api.vercel.app/blog/${id}`).then(
    (res) => res.json()
  )
  return (
    <main>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
    </main>
  )
}

Voici comment cet exemple fonctionne :

  1. Pendant next build, tous les articles de blog connus sont générés (il y en a 25 dans cet exemple)
  2. Toutes les requêtes vers ces pages (par exemple /blog/1) sont mises en cache et instantanées
  3. Après 60 secondes écoulées, la prochaine requête affichera toujours la page mise en cache (obsolète)
  4. Le cache est invalidé et une nouvelle version de la page commence à être générée en arrière-plan
  5. Une fois générée avec succès, Next.js affichera et mettra en cache la page mise à jour
  6. Si /blog/26 est demandé, Next.js générera et mettra en cache cette page à la demande

Référence

Configuration du segment de route

Fonctions

Exemples

Revalidation basée sur le temps

Ceci récupère et affiche une liste d'articles de blog sur /blog. Après une heure, le cache pour cette page est invalidé lors de la prochaine visite. Ensuite, en arrière-plan, une nouvelle version de la page est générée avec les derniers articles de blog.

interface Post {
  id: string
  title: string
  content: string
}

export const revalidate = 3600 // invalider toutes les heures

export default async function Page() {
  const data = await fetch('https://api.vercel.app/blog')
  const posts: Post[] = await data.json()
  return (
    <main>
      <h1>Articles de blog</h1>
      <ul>
        {posts.map((post) => (
          <li key={post.id}>{post.title}</li>
        ))}
      </ul>
    </main>
  )
}

Nous recommandons de définir un temps de revalidation élevé. Par exemple, 1 heure au lieu de 1 seconde. Si vous avez besoin de plus de précision, envisagez d'utiliser la revalidation à la demande. Si vous avez besoin de données en temps réel, envisagez de passer au rendu dynamique.

Revalidation à la demande avec revalidatePath

Pour une méthode plus précise de revalidation, invalidez les pages à la demande avec la fonction revalidatePath.

Par exemple, cette Action Serveur serait appelée après l'ajout d'un nouvel article. Peu importe comment vous récupérez vos données dans votre Composant Serveur, que ce soit en utilisant fetch ou en vous connectant à une base de données, cela effacera le cache pour toute la route et permettra au Composant Serveur de récupérer des données fraîches.

'use server'

import { revalidatePath } from 'next/cache'

export async function createPost() {
  // Invalider la route /posts dans le cache
  revalidatePath('/posts')
}

Voir une démo et explorer le code source.

Revalidation à la demande avec revalidateTag

Pour la plupart des cas d'usage, préférez invalider des chemins entiers. Si vous avez besoin d'un contrôle plus granulaire, vous pouvez utiliser la fonction revalidateTag. Par exemple, vous pouvez taguer des appels fetch individuels :

export default async function Page() {
  const data = await fetch('https://api.vercel.app/blog', {
    next: { tags: ['posts'] },
  })
  const posts = await data.json()
  // ...
}

Si vous utilisez un ORM ou vous connectez à une base de données, vous pouvez utiliser unstable_cache :

import { unstable_cache } from 'next/cache'
import { db, posts } from '@/lib/db'

const getCachedPosts = unstable_cache(
  async () => {
    return await db.select().from(posts)
  },
  ['posts'],
  { revalidate: 3600, tags: ['posts'] }
)

export default async function Page() {
  const posts = getCachedPosts()
  // ...
}

Vous pouvez ensuite utiliser revalidateTag dans une Action Serveur ou un Gestionnaire de Route :

'use server'

import { revalidateTag } from 'next/cache'

export async function createPost() {
  // Invalider toutes les données taguées avec 'posts' dans le cache
  revalidateTag('posts')
}

Gestion des exceptions non capturées

Si une erreur est levée lors de la tentative de revalidation des données, les dernières données générées avec succès continueront d'être servies depuis le cache. Lors de la prochaine requête, Next.js réessayera de revalider les données. En savoir plus sur la gestion des erreurs.

Personnalisation de l'emplacement du cache

Vous pouvez configurer l'emplacement du cache Next.js si vous souhaitez persister les pages et données mises en cache vers un stockage durable, ou partager le cache entre plusieurs conteneurs ou instances de votre application Next.js. En savoir plus.

Dépannage

Débogage des données mises en cache en développement local

Si vous utilisez l'API fetch, vous pouvez ajouter des logs supplémentaires pour comprendre quelles requêtes sont mises en cache ou non. En savoir plus sur l'option logging.

next.config.js
module.exports = {
  logging: {
    fetches: {
      fullUrl: true,
    },
  },
}

Vérification du comportement en production

Pour vérifier que vos pages sont correctement mises en cache et revalidées en production, vous pouvez tester localement en exécutant next build puis next start pour lancer le serveur Next.js en mode production.

Cela vous permettra de tester le comportement de l'ISR (Incremental Static Regeneration) tel qu'il fonctionnerait dans un environnement de production. Pour un débogage approfondi, ajoutez la variable d'environnement suivante à votre fichier .env :

.env
NEXT_PRIVATE_DEBUG_CACHE=1

Cela fera en sorte que le serveur Next.js enregistre dans la console les succès et les échecs du cache ISR. Vous pouvez inspecter la sortie pour voir quelles pages sont générées lors de next build, ainsi que comment les pages sont mises à jour lorsque les chemins sont accédés à la demande.

Mises en garde

  • L'ISR n'est pris en charge que lors de l'utilisation du runtime Node.js (par défaut).
  • L'ISR n'est pas pris en charge lors de la création d'une exportation statique.
  • Si vous avez plusieurs requêtes fetch dans une route rendue statiquement et que chacune a une fréquence de revalidate différente, le temps le plus court sera utilisé pour l'ISR. Cependant, ces fréquences de revalidation seront toujours respectées par le cache de données.
  • Si l'une des requêtes fetch utilisées sur une route a un temps de revalidate de 0 ou un no-store explicite, la route sera rendue dynamiquement.
  • Le middleware ne sera pas exécuté pour les requêtes ISR à la demande, ce qui signifie que toute réécriture de chemin ou logique dans le middleware ne sera pas appliquée. Assurez-vous de revalider le chemin exact. Par exemple, /post/1 au lieu d'un chemin réécrit /post-1.

Prise en charge par les plateformes

Option de déploiementPris en charge
Serveur Node.jsOui
Conteneur DockerOui
Exportation statiqueNon
AdaptateursDépend de la plateforme

Apprenez comment configurer l'ISR lors de l'hébergement autonome de Next.js.

Historique des versions

VersionModifications
v14.1.0Le cacheHandler personnalisé est stable.
v13.0.0L'App Router est introduit.
v12.2.0Pages Router : L'ISR à la demande est stable
v12.0.0Pages Router : ISR avec prise en compte des bots ajouté.
v9.5.0Pages Router : ISR stable introduit.