Guides

Bien demarrer

Next.js et Vercel : des reglages de cache surs pour le contenu public

Commencez par une route publique, rendez son contrat de fraicheur explicite, puis verifiez chaque couche avant d'elargir la politique.

Publié le
Sur cette page

La mise en cache sur Vercel n'est pas un unique interrupteur. Une application Next.js peut mettre en cache des donnees recuperees, prerendre une route et laisser le CDN de Vercel mettre en cache une reponse HTTP complete. Ces couches resolvent des problemes differents. Commencez par accelerer une reponse publique ; ne debutez pas par les pages de compte, les paniers, les API authentifiees ou toute reponse pouvant contenir des donnees specifiques a un utilisateur.

Un cache partage exige une sortie publique

Un cache partage peut servir une meme reponse stockee a de nombreux visiteurs. N'ajoutez jamais de politique de cache partage a une sortie qui varie selon la session, l'autorisation, un cookie, un droit ou l'etat d'un autre utilisateur. Gardez ces donnees dynamiques ou explicitement privees.

Ce que vous allez mettre en place

Ce guide met en cache un catalogue de produits public pendant cinq minutes dans le cache de donnees Next.js et montre comment mettre une reponse JSON publique distincte en cache dans le CDN de Vercel. Il utilise les options explicites de fetch, ce qui permet de l'utiliser sans activer les Cache Components de Next.js.

CoucheCe qu'elle stockePolitique de depart
Cache de donnees Next.jsLe resultat d'un fetch cote serveurRevalidation toutes les 300 secondes
Sortie de route Next.jsLa page rendue ou le resultat d'un Route HandlerLaisser les besoins de donnees de la route decider
CDN VercelUne reponse HTTP publique completeTTL partage court et revalidation en arriere-plan
NavigateurLa reponse locale d'un visiteurSeparer du TTL CDN partage

Etape 1 : choisir une route sure

Notez la premiere URL a mettre en cache et repondez a ces questions avant de modifier le code :

  1. La sortie est-elle identique pour tous les visiteurs qui peuvent la demander ?
  2. Evite-t-elle Set-Cookie, l'autorisation, les lectures de session et les parametres de requete specifiques a un utilisateur ?
  3. Un visiteur peut-il tolerer jusqu'a cinq minutes de donnees de catalogue anciennes ?
  4. Le responsable applicatif peut-il nommer l'evenement qui devra rafraichir le contenu plus tot ?

Pour ce guide, utilisez une liste publique /products. Gardez /account, /cart, /checkout et toute route API authentifiee hors du perimetre.

Etape 2 : rendre la politique de donnees publique explicite

Placez l'acces aux donnees publiques dans un module reserve au serveur. Donnez a l'appel fetch une politique temporelle et un tag que vous pourrez invalider plus tard.

// lib/catalog.ts
export type Product = {
  slug: string
  name: string
  price: number
}

export async function getCatalog(): Promise<Product[]> {
  const response = await fetch("https://api.example.com/catalog", {
    next: {
      revalidate: 300,
      tags: ["catalog"],
    },
  })

  if (!response.ok) {
    throw new Error("Unable to load the public catalog")
  }

  return response.json()
}

Utilisez ce module depuis une page Server Component :

// app/products/page.tsx
import { getCatalog } from "@/lib/catalog"

export default async function ProductsPage() {
  const products = await getCatalog()

  return (
    <main>
      <h1>Products</h1>
      <ul>
        {products.map((product) => (
          <li key={product.slug}>{product.name}</li>
        ))}
      </ul>
    </main>
  )
}

next.revalidate donne a ces donnees un age maximal en secondes. Le tag catalog n'a aucun effet tant que vous ne l'utilisez pas pour une revalidation a la demande dans un guide suivant, mais le definir maintenant donne aux evenements de publication une cible d'invalidation claire.

Etape 3 : maintenir les donnees privees hors du chemin partage

Pour une requete dependant du visiteur connecte, rendez l'intention non mise en cache explicite. N'essayez pas de creer une cle de cache a partir d'un token de session ou d'un identifiant utilisateur.

// lib/account.ts
export async function getAccount(accessToken: string) {
  const response = await fetch("https://api.example.com/account", {
    cache: "no-store",
    headers: {
      Authorization: `Bearer ${accessToken}`,
    },
  })

  if (!response.ok) {
    throw new Error("Unable to load account data")
  }

  return response.json()
}

Lire cookies() ou headers() ne transforme pas une reponse privee en representation partagee sure. Alignez la recuperation des donnees, le comportement de la page et les en-tetes HTTP avec l'exigence de confidentialite.

Etape 4 : mettre une reponse HTTP publique en cache dans le CDN Vercel

Le cache de donnees Next.js ne signifie pas automatiquement qu'une reponse HTTP complete est servie par le CDN. Pour un Route Handler deliberement public, renvoyez une reponse avec une politique de cache partage explicite :

// app/api/public-catalog/route.ts
import { getCatalog } from "@/lib/catalog"

export async function GET() {
  const products = await getCatalog()

  return Response.json(products, {
    headers: {
      "Cache-Control": "public, s-maxage=60, stale-while-revalidate=300",
    },
  })
}

Cette approche ne convient que lorsque chaque reponse est publique et identique pour la meme URL. Sur Vercel, le CDN consomme des directives de cache partage telles que s-maxage ; l'en-tete recu par le navigateur peut donc differer de la politique appliquee par Vercel. Inspectez x-vercel-cache et le corps de la reponse plutot que de supposer qu'un seul en-tete retourne prouve chaque couche.

N'ajoutez pas cette politique a une reponse qui definit un cookie, recoit un en-tete Authorization, varie selon l'utilisateur ou contient des donnees sensibles.

Etape 5 : deployer et rechauffer l'URL exacte

Deployez d'abord vers un environnement de preview. Demandez ensuite deux fois la meme URL publique et conservez les deux reponses avec l'enregistrement de changement :

curl -sS -I https://preview.example.com/api/public-catalog
curl -sS -I https://preview.example.com/api/public-catalog

Verifiez le statut, Cache-Control, x-vercel-cache, le type de contenu et les en-tetes de securite requis par l'application. Un premier MISS peut etre normal. Un HIT ou STALE ulterieur n'est utile que si le corps reste la representation publique correcte.

Apres verification de la preview, deployez le changement examine en production :

vercel deploy --prod

Etape 6 : mesurer le bon resultat

Suivez plus qu'un en-tete de statut de cache. Pour la route modifiee, comparez :

  • la latence de requete sur l'URL exposee aux visiteurs ;
  • le volume de requetes vers l'origine ou l'API amont ;
  • le taux d'erreur et la justesse des reponses ;
  • les signalements de contenu obsolete apres une mise a jour du catalogue ; et
  • le taux de requetes dynamiques qui ne doivent jamais etre partagees.

Le cache CDN de Vercel est regional : une requete depuis un emplacement ne prouve pas que chaque region est chaude. Testez un trafic representatif et conservez un petit objet de test public pour les futurs controles.

Retour arriere sur

Si la route renvoie un contenu incorrect, retirez d'abord le nouvel en-tete de cache partage ou restaurez le deploiement precedent. Invalidez ensuite uniquement les entrees de cache publiques concernees via le workflow Vercel examine. Ne repondez pas a un probleme d'isolation de donnees par une purge large seule : retirez d'abord l'eligibilite non sure, puis verifiez un parcours authentifie aussi bien que l'URL publique.

Avant d'elargir la politique

  • Chaque route cacheable a un responsable de donnees publiques et une cible de fraicheur documentes.
  • Les reponses privees et authentifiees utilisent no-store ou une conception privee equivalente.
  • Chaque reponse partagee dispose d'un chemin d'invalidation teste.
  • Les controles d'en-tete incluent le corps de la reponse ou un checksum, pas seulement un statut de cache.
  • La verification de preview precede le deploiement de production.

References faisant autorite

Faites du cache un comportement applicatif controle

Echangez avec Optimi sur les frontieres de cache, la validation CDN et la protection de l'origine pour les applications Next.js a fort trafic.

Discuter de l'architecture de cache