erklärt, wie die Dokumentationsseite schnelle statische Seitenladezeiten erreicht, während die CMS-Bearbeitungsmodus-Funktionalität erhalten bleibt
Dieser Leitfaden erklärt, wie die Dokumentationsseite schnelle statische Seitenladezeiten erreicht und dabei die CMS-Bearbeitungsmodus-Funktionalität beibehält.
Wir verwenden zwei Routen für denselben Inhalt:
app/
├── [...slug]/page.tsx # Produktion: force-static (schnell)
└── preview/[...slug]/page.tsx # Bearbeitungsmodus: force-dynamic (liest searchParams)
Eine Proxy-Middleware schreibt Bearbeitungsmodus-Anfragen transparent um:
Benutzeranfrage: /en/headless/quickstart?edit_mode=true
↓
Proxy erkennt ?edit_mode=true
↓
Interne Umschreibung zu: /preview/en/headless/quickstart?edit_mode=true
↓
Dynamische Route rendert mit Bearbeitungs-Wrappern
Der Benutzer sieht niemals /preview in seiner URL - es handelt sich um eine interne Umschreibung.
// app/[...slug]/page.tsx
export const dynamic = 'force-static';
export const revalidate = 60;
export default async function Page({ params }) {
// Keine searchParams - Seite ist vollständig statisch
// app/preview/[...slug]/page.tsx
export const dynamic = 'force-dynamic';
export default async function PreviewPage({ params, searchParams }) {
// searchParams verfügbar - kann edit_mode erkennen
return <ParametricRoutePage params={params
?edit_mode=true aus der URL lesen// src/proxy.ts
export const proxy = async (request: NextRequest) => {
const { pathname, searchParams } = request.nextUrl;
const editMode = searchParams.get('edit_mode');
| Szenario | Antwortzeit | Rendering |
|---|---|---|
| Produktionsseite (gecached) | ~50-100 ms | Statisch aus dem CDN |
| Produktionsseite (veraltet) | ~50-100 ms + Hintergrundaktualisierung | Statisch, anschließend ISR |
| Bearbeitungsmodus | ~500-1500 ms | Dynamisches SSR |
Die revalidate = 60-Einstellung aktiviert ISR. Das bedeutet NICHT, dass Seiten alle 60 Sekunden neu berechnet werden.
ISR verwendet ein stale-while-revalidate-Muster:
Anfrage trifft ein:
→ Ist die gecachte Seite < 60 s alt? → Aus dem Cache ausliefern (sofort)
→ Ist die gecachte Seite > 60 s alt? → Veralteten Cache ausliefern (sofort)
+ im Hintergrund für die nächste Anfrage revalidieren
Keine Anfragen = Keine Neuberechnung. Niemals.
Beispiel:
Das 60-Sekunden-Fenster ist ein Sicherheitsnetz. Idealerweise würden wir eine On-Demand-Revalidierung über Webhooks verwenden, wenn sich CMS-Inhalte ändern.
| Anwendungsfall | URL | Verwendete Route |
|---|---|---|
| Normales Browsen | /en/headless/quickstart | Statisch |
| CMS-Template-Builder | /en/headless/quickstart?edit_mode=true | Vorschau (über Umschreibung) |
| KI-Blockvorschau | /en/headless/quickstart?ai_preview=1 | Vorschau (über Umschreibung) |
Der einfache Ansatz (kein force-static, keine Vorschau-Route) funktioniert, ist aber langsam:
// Einfacher Ansatz - funktioniert, aber ~1-2 s pro Anfrage
export default async function Page({ params, searchParams }) {
return <ParametricRoutePage params={params} searchParams={searchParams} />;
}
Dies rendert bei jeder Anfrage dynamisch. Für eine Dokumentationsseite mit vielen Seiten bedeutet das:
Die Architektur mit zwei Routen bietet uns das Beste aus beiden Welten: statische Geschwindigkeit für Leser, dynamische Funktionalität für Redakteure.