spiega come il sito della documentazione ottiene caricamenti statici rapidi delle pagine mantenendo la funzionalità della modalità di modifica del CMS
Questa guida spiega come il sito della documentazione ottiene caricamenti statici rapidi delle pagine mantenendo la funzionalità della modalità di modifica del CMS.
Utilizziamo due route per lo stesso contenuto:
app/
├── [...slug]/page.tsx # Produzione: force-static (veloce)
└── preview/[...slug]/page.tsx # Modalità di modifica: force-dynamic (legge searchParams)
Un middleware proxy riscrive in modo trasparente le richieste della modalità di modifica:
Richiesta dell'utente: /en/headless/quickstart?edit_mode=true
↓
Il proxy rileva ?edit_mode=true
↓
Riscrittura interna in: /preview/en/headless/quickstart?edit_mode=true
↓
La route dinamica esegue il rendering con wrapper di modifica
L'utente non vede mai /preview nel proprio URL - è una riscrittura interna.
// app/[...slug]/page.tsx
export const dynamic = 'force-static';
export const revalidate = 60;
export default async function Page({ params }) {
// Nessun searchParams - la pagina è completamente statica
// app/preview/[...slug]/page.tsx
export const dynamic = 'force-dynamic';
export default async function PreviewPage({ params, searchParams }) {
// searchParams disponibile - può rilevare edit_mode
return <ParametricRoutePage params={params
?edit_mode=true dall'URL// src/proxy.ts
export const proxy = async (request: NextRequest) => {
const { pathname, searchParams } = request.nextUrl;
const editMode = searchParams.get('edit_mode');
| Scenario | Tempo di risposta | Rendering |
|---|---|---|
| Pagina di produzione (in cache) | ~50-100ms | Statico dalla CDN |
| Pagina di produzione (non aggiornata) | ~50-100ms + aggiornamento in background | Statica, poi ISR |
| Modalità di modifica | ~500-1500ms | SSR dinamico |
L'impostazione revalidate = 60 abilita l'ISR. Questo NON significa che le pagine vengano ricalcolate ogni 60 secondi.
L'ISR utilizza uno schema stale-while-revalidate:
Richiesta in ingresso:
→ La pagina in cache ha meno di 60 s? → Servi dalla cache (istantaneo)
→ La pagina in cache ha più di 60 s? → Servi la cache obsoleta (istantaneo)
+ rivalida in background per la richiesta successiva
Nessuna richiesta = Nessuna ricalcolazione. Mai.
Esempio:
La finestra di 60 secondi è una rete di sicurezza. Idealmente, useremmo la rivalidazione on-demand tramite webhook quando il contenuto del CMS cambia.
| Caso d'uso | URL | Route utilizzata |
|---|---|---|
| Navigazione normale | /en/headless/quickstart | Statica |
| Costruttore di template del CMS | /en/headless/quickstart?edit_mode=true | Anteprima (tramite riscrittura) |
| Anteprima blocco AI | /en/headless/quickstart?ai_preview=1 | Anteprima (tramite riscrittura) |
L'approccio semplice (nessun force-static, nessuna route di anteprima) funziona ma è lento:
// Approccio semplice - funziona ma ~1-2s per richiesta
export default async function Page({ params, searchParams }) {
return <ParametricRoutePage params={params} searchParams={searchParams} />;
}
Questo esegue il rendering in modo dinamico a ogni richiesta. Per un sito di documentazione con molte pagine, ciò significa:
L'architettura a doppia route ci offre il meglio di entrambi i mondi: velocità statica per i lettori, funzionalità dinamica per gli editor.