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

Statische Rendering Met Ondersteuning Voor Bewerkmodus

legt uit hoe de documentatiesite snelle statische paginaladingen bereikt terwijl de CMS-bewerkmodus behouden blijft

Continue Reading
Previous‹Instellen Beheerderspaneel ProxyNextScripting In Sjabloonbouwer›

Hybride

Renderer ProjectParametrische RouteringComponenttypenSseInstellen Beheerderspaneel ProxyStatische Rendering Met Ondersteuning Voor BewerkmodusScripting In SjabloonbouwerCreate Profound Next

Koploos

SnelstartJson En Claude CodeComponent Zod Ophalen

Mcp

Mcp

Cms Functies

Feat Docs TemplateFeat SjabloonbouwerFeat VertalerFeat Organisatie

Motivatie

Onze Aanpak

Terminologie

Hybride Vs Headless

Deze gids legt uit hoe de documentatiesite snelle statische paginaladingen bereikt terwijl de CMS-bewerkmodus behouden blijft.

Architectuur met dubbele route

We gebruiken twee routes voor dezelfde inhoud:

app/
├── [...slug]/page.tsx          # Productie: force-static (snel)
└── preview/[...slug]/page.tsx  # Bewerkmodus: force-dynamic (leest searchParams)

Een proxy-middleware herschrijft bewerkingsmodus-aanvragen transparant:

Gebruiker vraagt: /en/headless/quickstart?edit_mode=true
       ↓
Proxy detecteert ?edit_mode=true
       ↓
Interne herschrijving naar: /preview/en/headless/quickstart?edit_mode=true
       ↓
Dynamische route rendert met bewerkingswrappers

De gebruiker ziet /preview nooit in de URL - het is een interne herschrijving.

Hoe het werkt

Productiepad (standaard)

// app/[...slug]/page.tsx
export const dynamic = 'force-static';
export const revalidate = 60;

export default async function Page({ params }) {
  // Geen searchParams - pagina is volledig statisch
  
  • Pagina's worden vooraf gerenderd tijdens de build
  • Onmiddellijk bediend vanuit de CDN-edgecache
  • Om de 60 seconden (ISR) opnieuw gevalideerd als vangnet

Pad voor bewerkingsmodus

// app/preview/[...slug]/page.tsx
export const dynamic = 'force-dynamic';

export default async function PreviewPage({ params, searchParams }) {
  // searchParams beschikbaar - kan edit_mode detecteren
  return <ParametricRoutePage params={params
  • Gerenderd bij elk verzoek
  • Kan ?edit_mode=true uit de URL lezen
  • Rendeert met CMS-bewerkbare wrappers en blokomtrekken

De proxy-herschrijving

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

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

Prestatievergelijking

ScenarioResponstijdRendering
Productiepagina (in cache)~50-100 msStatisch vanaf CDN
Productiepagina (verouderd)~50-100 ms + achtergrondvernieuwingStatisch, daarna ISR
Bewerkmodus~500-1500 msDynamische SSR

ISR (Incremental Static Regeneration) begrijpen

De instelling revalidate = 60 schakelt ISR in. Dit betekent NIET dat pagina's elke 60 seconden opnieuw worden berekend.

ISR gebruikt een stale-while-revalidate-patroon:

Aanvraag komt binnen:
  → Is de gecachte pagina < 60 s oud? → Serveer uit de cache (direct)
  → Is de gecachte pagina > 60 s oud? → Serveer verouderde cache (direct)
                                + valideer op de achtergrond voor het volgende verzoek

Geen aanvragen = geen herberekening. Nooit.

Voorbeeld:

  • Pagina in cache om 10:00 uur
  • Geen bezoekers tot 15:00 uur
  • Eerste bezoeker om 15:00 uur krijgt onmiddellijk de verouderde cache
  • Achtergrondvernieuwing vindt plaats, volgende bezoeker krijgt verse inhoud

Het venster van 60 seconden is een vangnet. Idealiter gebruiken we on-demand revalidatie via webhooks wanneer CMS-inhoud verandert.

Wanneer welke route te gebruiken

GebruiksscenarioURLGebruikte route
Normaal browsen/en/headless/quickstartStatisch
CMS-templatebouwer/en/headless/quickstart?edit_mode=truePreview (via herschrijving)
AI-blokpreview/en/headless/quickstart?ai_preview=1Preview (via herschrijving)

Waarom niet gewoon dynamische rendering gebruiken?

De eenvoudige aanpak (geen force-static, geen preview-route) werkt maar is traag:

// Eenvoudige aanpak - werkt maar ~1-2 s per verzoek
export default async function Page({ params, searchParams }) {
  return <ParametricRoutePage params={params} searchParams={searchParams} />;
}

Dit rendert dynamisch bij elk verzoek. Voor een documentatiesite met veel pagina's betekent dit:

  • Cold starts op elke pagina
  • Geen voordeel van CDN-edgecaching
  • Laadtijden van 1-2 seconden versus milliseconden

De architectuur met dubbele route geeft ons het beste van twee werelden: statische snelheid voor lezers, dynamische functionaliteit voor redacteuren.

return
<
ParametricRoutePage
params
={
params
} />;
}
}
searchParams
={
searchParams
} />;
}
const
aiPreview
=
searchParams.
get
(
'ai_preview'
);
// Herschrijf naar preview-route als edit_mode of ai_preview aanwezig is
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();
};