explique comment le site de documentation obtient des chargements de pages statiques rapides tout en conservant la fonctionnalité du mode édition du CMS
Ce guide explique comment le site de documentation obtient des chargements de pages statiques rapides tout en conservant la fonctionnalité du mode édition du CMS.
Nous utilisons deux routes pour le même contenu :
app/
├── [...slug]/page.tsx # Production : force-static (rapide)
└── preview/[...slug]/page.tsx # Mode édition : force-dynamic (lit searchParams)
Un middleware proxy réécrit de manière transparente les requêtes en mode édition :
Requête de l'utilisateur : /en/headless/quickstart?edit_mode=true
↓
Le proxy détecte ?edit_mode=true
↓
Réécriture interne vers : /preview/en/headless/quickstart?edit_mode=true
↓
La route dynamique rend avec des wrappers d'édition
L'utilisateur ne voit jamais /preview dans son URL - c'est une réécriture interne.
// app/[...slug]/page.tsx
export const dynamic = 'force-static';
export const revalidate = 60;
export default async function Page({ params }) {
// Pas de searchParams - la page est entièrement statique
// app/preview/[...slug]/page.tsx
export const dynamic = 'force-dynamic';
export default async function PreviewPage({ params, searchParams }) {
// searchParams disponibles - peut détecter edit_mode
return <ParametricRoutePage params={params
?edit_mode=true depuis l'URL// src/proxy.ts
export const proxy = async (request: NextRequest) => {
const { pathname, searchParams } = request.nextUrl;
const editMode = searchParams.get('edit_mode');
| Scénario | Temps de réponse | Rendu |
|---|---|---|
| Page de production (en cache) | ~50-100 ms | Statique depuis le CDN |
| Page de production (périmée) | ~50-100 ms + actualisation en arrière-plan | Statique, puis ISR |
| Mode édition | ~500-1500 ms | SSR dynamique |
Le paramètre revalidate = 60 active l'ISR. Cela ne signifie PAS que les pages sont recalculées toutes les 60 secondes.
L'ISR utilise un modèle stale-while-revalidate :
Une requête arrive :
→ La page en cache a-t-elle moins de 60 s ? → Servir depuis le cache (instantané)
→ La page en cache a-t-elle plus de 60 s ? → Servir le cache périmé (instantané)
+ revalider en arrière-plan pour la requête suivante
Pas de requêtes = Pas de recalcul. Jamais.
Exemple :
La fenêtre de 60 secondes est un filet de sécurité. Idéalement, nous utiliserions une revalidation à la demande via des webhooks lorsque le contenu du CMS change.
| Cas d'utilisation | URL | Route utilisée |
|---|---|---|
| Navigation normale | /en/headless/quickstart | Statique |
| Constructeur de modèles du CMS | /en/headless/quickstart?edit_mode=true | Preview (via réécriture) |
| Prévisualisation de bloc IA | /en/headless/quickstart?ai_preview=1 | Preview (via réécriture) |
L'approche simple (pas de force-static, pas de route de prévisualisation) fonctionne mais est lente :
// Approche simple - fonctionne mais ~1-2 s par requête
export default async function Page({ params, searchParams }) {
return <ParametricRoutePage params={params} searchParams={searchParams} />;
}
Cela effectue un rendu dynamique à chaque requête. Pour un site de documentation avec de nombreuses pages, cela signifie :
L'architecture à double route nous offre le meilleur des deux mondes : la vitesse statique pour les lecteurs, la fonctionnalité dynamique pour les éditeurs.