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.
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.
| Couche | Ce qu'elle stocke | Politique de depart |
|---|---|---|
| Cache de donnees Next.js | Le resultat d'un fetch cote serveur | Revalidation toutes les 300 secondes |
| Sortie de route Next.js | La page rendue ou le resultat d'un Route Handler | Laisser les besoins de donnees de la route decider |
| CDN Vercel | Une reponse HTTP publique complete | TTL partage court et revalidation en arriere-plan |
| Navigateur | La reponse locale d'un visiteur | Separer 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 :
- La sortie est-elle identique pour tous les visiteurs qui peuvent la demander ?
- Evite-t-elle
Set-Cookie, l'autorisation, les lectures de session et les parametres de requete specifiques a un utilisateur ? - Un visiteur peut-il tolerer jusqu'a cinq minutes de donnees de catalogue anciennes ?
- 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-storeou 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
- Mise en cache et revalidation Next.js
- Reference de l'API
fetchNext.js - Vercel CDN Cache
- En-tetes Cache-Control Vercel
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