All Systems Operational
Powered By
profound-logo
profound-logoProfound CMS
⌘K
Admin

Statisches Rendering mit Edit-Modus-Unterstützung

erklärt, wie die Dokumentationsseite schnelle statische Seitenladezeiten erreicht, während die CMS-Bearbeitungsmodus-Funktionalität erhalten bleibt

Continue Reading
Previous‹Admin Panel Proxy EinrichtenNextSkripterstellung im Template-Builder›

Hybrid

Renderer-ProjektParametrisches RoutingKomponententypenSseAdmin Panel Proxy EinrichtenStatisches Rendering mit Edit-Modus-UnterstützungSkripterstellung im Template-BuilderCreate Profound Next

Kopflos

SchnellstartJson Und Claude CodeKomponente-Zod-Abruf

Mcp

Mcp

Cms Funktionen

Feat Docs TemplateFeat Vorlagen BuilderFeat TranslatorFeature-Organisation

Motivation

Unser Ansatz

Terminologie

Hybrid vs. Headless

Dieser Leitfaden erklärt, wie die Dokumentationsseite schnelle statische Seitenladezeiten erreicht und dabei die CMS-Bearbeitungsmodus-Funktionalität beibehält.

Architektur mit zwei Routen

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.

Funktionsweise

Produktionspfad (Standard)

// 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
  
  • Seiten werden zur Build-Zeit vorgerendert
  • Werden sofort aus dem CDN-Edge-Cache ausgeliefert
  • Alle 60 Sekunden (ISR) als Sicherheitsnetz revalidiert

Bearbeitungsmodus-Pfad

// 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
  • Wird bei jeder Anfrage gerendert
  • Kann ?edit_mode=true aus der URL lesen
  • Rendert mit CMS-bearbeitbaren Wrappern und Blockumrandungen

Die Proxy-Umschreibung

// src/proxy.ts
export const proxy = async (request: NextRequest) => {
  const { pathname, searchParams } = request.nextUrl;

  const editMode = searchParams.get('edit_mode');

Leistungsvergleich

SzenarioAntwortzeitRendering
Produktionsseite (gecached)~50-100 msStatisch aus dem CDN
Produktionsseite (veraltet)~50-100 ms + HintergrundaktualisierungStatisch, anschließend ISR
Bearbeitungsmodus~500-1500 msDynamisches SSR

ISR (Incremental Static Regeneration) verstehen

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:

  • Seite um 10:00 Uhr gecacht
  • Keine Besucher bis 15:00 Uhr
  • Erster Besucher um 15:00 Uhr erhält sofort den veralteten Cache
  • Hintergrundaktualisierung erfolgt, der nächste Besucher erhält frische Inhalte

Das 60-Sekunden-Fenster ist ein Sicherheitsnetz. Idealerweise würden wir eine On-Demand-Revalidierung über Webhooks verwenden, wenn sich CMS-Inhalte ändern.

Wann welche Route verwendet werden sollte

AnwendungsfallURLVerwendete Route
Normales Browsen/en/headless/quickstartStatisch
CMS-Template-Builder/en/headless/quickstart?edit_mode=trueVorschau (über Umschreibung)
KI-Blockvorschau/en/headless/quickstart?ai_preview=1Vorschau (über Umschreibung)

Warum nicht einfach dynamisches Rendering verwenden?

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:

  • Cold Starts auf jeder Seite
  • Kein CDN-Edge-Caching-Vorteil
  • 1-2 Sekunden Ladezeit statt Millisekunden

Die Architektur mit zwei Routen bietet uns das Beste aus beiden Welten: statische Geschwindigkeit für Leser, dynamische Funktionalität für Redakteure.

return
<
ParametricRoutePage
params
={
params
} />;
}
}
searchParams
={
searchParams
} />;
}
const
aiPreview
=
searchParams.
get
(
'ai_preview'
);
// Umschreiben zur Vorschau-Route, wenn edit_mode oder ai_preview vorhanden ist
if ((editMode === 'true' || editMode === '1' || aiPreview) && !pathname.startsWith('/preview')) {
const url = request.nextUrl.clone();
url.pathname = `/preview${pathname}`;
return NextResponse.rewrite(url);
}
return NextResponse.next();
};