De manier waarop je website HTML genereert, bepaalt of AI-crawlers je content kunnen lezen. De meeste AI-bots — GPTBot, PerplexityBot, ClaudeBot — voeren geen JavaScript uit. Ze lezen de ruwe HTML die je server teruggeeft. Als je content pas zichtbaar wordt na het uitvoeren van JavaScript, is je site effectief onzichtbaar voor AI.
In dit artikel vergelijken we vier rendering-strategieën en laten we per framework zien hoe je je site optimaal inricht voor AI-zichtbaarheid.
Waarom rendering ertoe doet voor AI-crawlers
Traditionele zoekmachines zoals Google hebben geavanceerde rendering-engines die JavaScript kunnen uitvoeren. Googlebot draait een volledige Chromium-instantie om pagina's te renderen. AI-crawlers doen dit meestal niet.
De reden is praktisch: AI-crawlers moeten miljoenen pagina's per dag verwerken. Het renderen van JavaScript is computationeel duur en traag. Daarom downloaden ze simpelweg de HTML en gaan verder.
Dit heeft een directe consequentie: als je content niet in de initiële HTML-response zit, bestaat het niet voor AI-modellen. Geen indexering, geen embeddings, geen citaties.
De vier rendering-strategieën vergeleken
CSR (Client-Side Rendering)
Bij CSR stuurt de server een leeg HTML-skelet naar de browser. JavaScript downloadt vervolgens data en bouwt de pagina op in de browser.
<!-- Wat de server stuurt bij CSR -->
<html>
<body>
<div id="app"></div>
<script src="/bundle.js"></script>
</body>
</html>
Dit is wat een AI-crawler ziet: een lege div. Geen content, geen context, geen bruikbare informatie.
Verdict voor AI: Slecht. Vermijd CSR voor pagina's die je zichtbaar wilt maken in AI-antwoorden.
SSR (Server-Side Rendering)
Bij SSR genereert de server de volledige HTML voor elke request. De browser ontvangt een complete pagina met alle content.
<!-- Wat de server stuurt bij SSR -->
<html>
<body>
<article>
<h1>Wat is GEO?</h1>
<p>Generative Engine Optimization is de strategie om...</p>
</article>
</body>
</html>
AI-crawlers ontvangen dezelfde volledige HTML als een browser. Alle content is direct beschikbaar.
Verdict voor AI: Goed. Content is volledig beschikbaar bij de eerste request.
SSG (Static Site Generation)
Bij SSG worden pagina's vooraf gebouwd tijdens het build-proces. De server serveert kant-en-klare HTML-bestanden.
<!-- Vooraf gegenereerd HTML-bestand -->
<html>
<body>
<article>
<h1>Wat is GEO?</h1>
<p>Generative Engine Optimization is de strategie om...</p>
</article>
</body>
</html>
Het resultaat is identiek aan SSR, maar dan sneller: er is geen rendering nodig per request.
Verdict voor AI: Uitstekend. Snelste response time, volledige content, minimale serverbelasting.
ISR (Incremental Static Regeneration)
ISR combineert SSG met de mogelijkheid om pagina's op de achtergrond te vernieuwen. Pagina's worden statisch geserveerd, maar periodiek opnieuw gegenereerd.
Verdict voor AI: Goed. Combineert de snelheid van SSG met de actualiteit van SSR.
Vergelijkingstabel
| Criterium |
CSR |
SSR |
SSG |
ISR |
| HTML-content bij eerste request |
Leeg |
Volledig |
Volledig |
Volledig |
| Leesbaar voor AI-crawlers |
Nee |
Ja |
Ja |
Ja |
| Response tijd |
Snel (leeg) |
Variabel |
Zeer snel |
Zeer snel |
| Serverbelasting |
Laag |
Hoog |
Minimaal |
Laag |
| Content actualiteit |
Real-time |
Real-time |
Bij build |
Configureerbaar |
| Geschikt voor GEO |
Nee |
Ja |
Ja (beste) |
Ja |
De conclusie is duidelijk: voor pagina's die je in AI-antwoorden wilt laten verschijnen, moet je SSR, SSG of ISR gebruiken. CSR is geen optie.
Framework-specifieke implementaties
Next.js
Next.js biedt alle vier de rendering-strategieën. Voor AI-zichtbaarheid zijn er twee belangrijke benaderingen.
#### Pages Router: getStaticProps (SSG)
// pages/blog/[slug].js — SSG met Next.js Pages Router
export async function getStaticProps({ params }) {
const article = await getArticleBySlug(params.slug);
return {
props: { article },
revalidate: 3600, // ISR: hervalideer elke 60 minuten
};
}
export async function getStaticPaths() {
const slugs = await getAllArticleSlugs();
return {
paths: slugs.map((slug) => ({ params: { slug } })),
fallback: 'blocking', // Genereer nieuwe pagina's on-demand
};
}
export default function BlogPost({ article }) {
return (
<article>
<h1>{article.title}</h1>
<div dangerouslySetInnerHTML={{ __html: article.content }} />
</article>
);
}
Met revalidate: 3600 krijg je ISR: statische pagina's die elk uur worden vernieuwd. De fallback: 'blocking' zorgt ervoor dat nieuwe pagina's bij het eerste bezoek server-side worden gerenderd en daarna gecacht.
#### App Router: Server Components (standaard SSR/SSG)
// app/blog/[slug]/page.js — Next.js App Router
export async function generateStaticParams() {
const articles = await getAllArticles();
return articles.map((article) => ({ slug: article.slug }));
}
export default async function BlogPost({ params }) {
const article = await getArticleBySlug(params.slug);
return (
<article>
<h1>{article.title}</h1>
<div dangerouslySetInnerHTML={{ __html: article.content }} />
</article>
);
}
// Optioneel: ISR-achtig gedrag
export const revalidate = 3600;
In de App Router zijn componenten standaard Server Components. Ze worden op de server gerenderd en sturen volledige HTML naar de client. Dit is ideaal voor AI-crawlers.
Nuxt (Vue)
Nuxt biedt universal rendering (SSR) als standaardmodus.
// nuxt.config.ts
export default defineNuxtConfig({
ssr: true, // Standaard aan, maar expliciet maken
routeRules: {
'/blog/**': { swr: 3600 }, // ISR voor blog-pagina's
'/docs/**': { prerender: true }, // SSG voor documentatie
},
});
<!-- pages/blog/[slug].vue -->
<script setup>
const route = useRoute();
const { data: article } = await useFetch(\`/api/articles/\${route.params.slug}\`);
</script>
<template>
<article>
<h1>{{ article.title }}</h1>
<div v-html="article.content" />
</article>
</template>
useFetch in Nuxt voert data-ophaling uit op de server bij SSR. De resulterende HTML bevat de volledige content — precies wat AI-crawlers nodig hebben.
Met routeRules kun je per route bepalen welke strategie je gebruikt. Blog-pagina's met swr: 3600 krijgen ISR-gedrag, terwijl documentatie volledig statisch wordt gegenereerd.
Astro
Astro is ontworpen met een static-first filosofie en het islands architecture-patroon. Standaard genereert Astro volledig statische HTML.
---
// src/pages/blog/[slug].astro
import Layout from '../../layouts/Layout.astro';
import { getArticleBySlug, getAllArticleSlugs } from '../../lib/articles';
export async function getStaticPaths() {
const slugs = await getAllArticleSlugs();
return slugs.map((slug) => ({
params: { slug },
props: { article: await getArticleBySlug(slug) },
}));
}
const { article } = Astro.props;
---
<Layout title={article.title}>
<article>
<h1>{article.title}</h1>
<Fragment set:html={article.content} />
</article>
<!-- Interactief component als "island" — alleen dit laadt JavaScript -->
<ShareButtons client:idle />
</Layout>
Het islands-patroon is bijzonder geschikt voor GEO: de pagina is volledig statische HTML, terwijl interactieve componenten (zoals deelknoppen of zoekbalken) als losse "eilanden" JavaScript laden. AI-crawlers krijgen de volledige content zonder enig JavaScript nodig te hebben.
Testen of AI-crawlers je content kunnen lezen
De eenvoudigste manier om te controleren of je content zichtbaar is voor AI-crawlers is met curl:
# Bekijk de HTML zoals een AI-crawler het ziet
curl -s https://jouwsite.nl/blog/artikel | head -100
# Zoek naar specifieke content in de response
curl -s https://jouwsite.nl/blog/artikel | grep -i "je belangrijkste heading"
# Simuleer een specifieke AI-crawler
curl -s -H "User-Agent: GPTBot/1.0" https://jouwsite.nl/blog/artikel | head -100
Als je heading en body-tekst in de curl-output staan, kunnen AI-crawlers het lezen. Staat er alleen een lege of
, dan heb je een CSR-probleem.
Je kunt ook in je browser "Paginabron weergeven" gebruiken (Ctrl+U). Dit toont de ruwe HTML, niet de gerenderde DOM. Als je content daar niet zichtbaar is, is het ook onzichtbaar voor AI-bots.
Geautomatiseerde controle
Voor grotere sites kun je een script schrijven dat automatisch controleert of belangrijke pagina's volledige HTML teruggeven:
#!/bin/bash
# check-ssr.sh — Controleer of pagina's server-side gerenderd worden
URLS=(
"https://jouwsite.nl/blog/artikel-1"
"https://jouwsite.nl/blog/artikel-2"
"https://jouwsite.nl/diensten"
)
for url in "\${URLS[@]}"; do
CONTENT_LENGTH=$(curl -s "$url" | wc -c)
HAS_CONTENT=$(curl -s "$url" | grep -c "<article")
if [ "$HAS_CONTENT" -gt 0 ] && [ "$CONTENT_LENGTH" -gt 5000 ]; then
echo "OK: $url ($CONTENT_LENGTH bytes)"
else
echo "WAARSCHUWING: $url — mogelijk geen SSR ($CONTENT_LENGTH bytes)"
fi
done
Veelgemaakte fouten
- SPA zonder SSR deployen. React of Vue apps die puur client-side renderen. Lees meer hierover in ons artikel over GEO-fouten bij React SPA's zonder SSR.
- Dynamische content achter
useEffect of onMounted. Data die pas na mount wordt opgehaald, is onzichtbaar in de initiële HTML.
- Loading states als enige content. Als je HTML alleen "Laden..." bevat totdat JavaScript klaar is, is dat alles wat een AI-crawler ziet.
- API-routes zonder fallback. Als je content via een client-side API-call ophaalt zonder server-side fallback, is de content onzichtbaar.
Conclusie
Voor maximale AI-zichtbaarheid is de keuze helder: gebruik SSG waar mogelijk, ISR voor content die regelmatig verandert, en SSR als fallback voor zeer dynamische pagina's. Vermijd CSR voor elke pagina die je in AI-antwoorden wilt laten verschijnen.
De technische implementatie verschilt per framework, maar het principe is universeel: zorg dat je volledige content in de eerste HTML-response zit.
Wil je een breder overzicht van alle technische vereisten voor AI-zichtbaarheid? Bekijk dan onze Technische GEO-checklist. En als je al weet dat je SPA een probleem vormt, lees dan GEO-fouten bij React SPA zonder SSR.
Lees ook
Meet je AI-zichtbaarheid
Ontdek waar jouw bedrijf verschijnt in ChatGPT, Perplexity en andere AI-zoekmachines.
Probeer Briljant 7 dagen gratis
Server-side rendering (SSR) en AI-zichtbaarheid: technische deep-dive
De manier waarop je website HTML genereert, bepaalt of AI-crawlers je content kunnen lezen. De meeste AI-bots — GPTBot, PerplexityBot, ClaudeBot — voeren geen JavaScript uit. Ze lezen de ruwe HTML die je server teruggeeft. Als je content pas zichtbaar wordt na het uitvoeren van JavaScript, is je site effectief onzichtbaar voor AI.
In dit artikel vergelijken we vier rendering-strategieën en laten we per framework zien hoe je je site optimaal inricht voor AI-zichtbaarheid.
Waarom rendering ertoe doet voor AI-crawlers
Traditionele zoekmachines zoals Google hebben geavanceerde rendering-engines die JavaScript kunnen uitvoeren. Googlebot draait een volledige Chromium-instantie om pagina's te renderen. AI-crawlers doen dit meestal niet.
De reden is praktisch: AI-crawlers moeten miljoenen pagina's per dag verwerken. Het renderen van JavaScript is computationeel duur en traag. Daarom downloaden ze simpelweg de HTML en gaan verder.
Dit heeft een directe consequentie: als je content niet in de initiële HTML-response zit, bestaat het niet voor AI-modellen. Geen indexering, geen embeddings, geen citaties.
De vier rendering-strategieën vergeleken
CSR (Client-Side Rendering)
Bij CSR stuurt de server een leeg HTML-skelet naar de browser. JavaScript downloadt vervolgens data en bouwt de pagina op in de browser.
<!-- Wat de server stuurt bij CSR -->
<html>
<body>
<div id="app"></div>
<script src="/bundle.js"></script>
</body>
</html>
Dit is wat een AI-crawler ziet: een lege div. Geen content, geen context, geen bruikbare informatie.
Verdict voor AI: Slecht. Vermijd CSR voor pagina's die je zichtbaar wilt maken in AI-antwoorden.
SSR (Server-Side Rendering)
Bij SSR genereert de server de volledige HTML voor elke request. De browser ontvangt een complete pagina met alle content.
<!-- Wat de server stuurt bij SSR -->
<html>
<body>
<article>
<h1>Wat is GEO?</h1>
<p>Generative Engine Optimization is de strategie om...</p>
</article>
</body>
</html>
AI-crawlers ontvangen dezelfde volledige HTML als een browser. Alle content is direct beschikbaar.
Verdict voor AI: Goed. Content is volledig beschikbaar bij de eerste request.
SSG (Static Site Generation)
Bij SSG worden pagina's vooraf gebouwd tijdens het build-proces. De server serveert kant-en-klare HTML-bestanden.
<!-- Vooraf gegenereerd HTML-bestand -->
<html>
<body>
<article>
<h1>Wat is GEO?</h1>
<p>Generative Engine Optimization is de strategie om...</p>
</article>
</body>
</html>
Het resultaat is identiek aan SSR, maar dan sneller: er is geen rendering nodig per request.
Verdict voor AI: Uitstekend. Snelste response time, volledige content, minimale serverbelasting.
ISR (Incremental Static Regeneration)
ISR combineert SSG met de mogelijkheid om pagina's op de achtergrond te vernieuwen. Pagina's worden statisch geserveerd, maar periodiek opnieuw gegenereerd.
Verdict voor AI: Goed. Combineert de snelheid van SSG met de actualiteit van SSR.
Vergelijkingstabel
| Criterium |
CSR |
SSR |
SSG |
ISR |
| HTML-content bij eerste request |
Leeg |
Volledig |
Volledig |
Volledig |
| Leesbaar voor AI-crawlers |
Nee |
Ja |
Ja |
Ja |
| Response tijd |
Snel (leeg) |
Variabel |
Zeer snel |
Zeer snel |
| Serverbelasting |
Laag |
Hoog |
Minimaal |
Laag |
| Content actualiteit |
Real-time |
Real-time |
Bij build |
Configureerbaar |
| Geschikt voor GEO |
Nee |
Ja |
Ja (beste) |
Ja |
De conclusie is duidelijk: voor pagina's die je in AI-antwoorden wilt laten verschijnen, moet je SSR, SSG of ISR gebruiken. CSR is geen optie.
Framework-specifieke implementaties
Next.js
Next.js biedt alle vier de rendering-strategieën. Voor AI-zichtbaarheid zijn er twee belangrijke benaderingen.
#### Pages Router: getStaticProps (SSG)
// pages/blog/[slug].js — SSG met Next.js Pages Router
export async function getStaticProps({ params }) {
const article = await getArticleBySlug(params.slug);
return {
props: { article },
revalidate: 3600, // ISR: hervalideer elke 60 minuten
};
}
export async function getStaticPaths() {
const slugs = await getAllArticleSlugs();
return {
paths: slugs.map((slug) => ({ params: { slug } })),
fallback: 'blocking', // Genereer nieuwe pagina's on-demand
};
}
export default function BlogPost({ article }) {
return (
<article>
<h1>{article.title}</h1>
<div dangerouslySetInnerHTML={{ __html: article.content }} />
</article>
);
}
Met revalidate: 3600 krijg je ISR: statische pagina's die elk uur worden vernieuwd. De fallback: 'blocking' zorgt ervoor dat nieuwe pagina's bij het eerste bezoek server-side worden gerenderd en daarna gecacht.
#### App Router: Server Components (standaard SSR/SSG)
// app/blog/[slug]/page.js — Next.js App Router
export async function generateStaticParams() {
const articles = await getAllArticles();
return articles.map((article) => ({ slug: article.slug }));
}
export default async function BlogPost({ params }) {
const article = await getArticleBySlug(params.slug);
return (
<article>
<h1>{article.title}</h1>
<div dangerouslySetInnerHTML={{ __html: article.content }} />
</article>
);
}
// Optioneel: ISR-achtig gedrag
export const revalidate = 3600;
In de App Router zijn componenten standaard Server Components. Ze worden op de server gerenderd en sturen volledige HTML naar de client. Dit is ideaal voor AI-crawlers.
Nuxt (Vue)
Nuxt biedt universal rendering (SSR) als standaardmodus.
// nuxt.config.ts
export default defineNuxtConfig({
ssr: true, // Standaard aan, maar expliciet maken
routeRules: {
'/blog/**': { swr: 3600 }, // ISR voor blog-pagina's
'/docs/**': { prerender: true }, // SSG voor documentatie
},
});
<!-- pages/blog/[slug].vue -->
<script setup>
const route = useRoute();
const { data: article } = await useFetch(\`/api/articles/\${route.params.slug}\`);
</script>
<template>
<article>
<h1>{{ article.title }}</h1>
<div v-html="article.content" />
</article>
</template>
useFetch in Nuxt voert data-ophaling uit op de server bij SSR. De resulterende HTML bevat de volledige content — precies wat AI-crawlers nodig hebben.
Met routeRules kun je per route bepalen welke strategie je gebruikt. Blog-pagina's met swr: 3600 krijgen ISR-gedrag, terwijl documentatie volledig statisch wordt gegenereerd.
Astro
Astro is ontworpen met een static-first filosofie en het islands architecture-patroon. Standaard genereert Astro volledig statische HTML.
---
// src/pages/blog/[slug].astro
import Layout from '../../layouts/Layout.astro';
import { getArticleBySlug, getAllArticleSlugs } from '../../lib/articles';
export async function getStaticPaths() {
const slugs = await getAllArticleSlugs();
return slugs.map((slug) => ({
params: { slug },
props: { article: await getArticleBySlug(slug) },
}));
}
const { article } = Astro.props;
---
<Layout title={article.title}>
<article>
<h1>{article.title}</h1>
<Fragment set:html={article.content} />
</article>
<!-- Interactief component als "island" — alleen dit laadt JavaScript -->
<ShareButtons client:idle />
</Layout>
Het islands-patroon is bijzonder geschikt voor GEO: de pagina is volledig statische HTML, terwijl interactieve componenten (zoals deelknoppen of zoekbalken) als losse "eilanden" JavaScript laden. AI-crawlers krijgen de volledige content zonder enig JavaScript nodig te hebben.
Testen of AI-crawlers je content kunnen lezen
De eenvoudigste manier om te controleren of je content zichtbaar is voor AI-crawlers is met curl:
# Bekijk de HTML zoals een AI-crawler het ziet
curl -s https://jouwsite.nl/blog/artikel | head -100
# Zoek naar specifieke content in de response
curl -s https://jouwsite.nl/blog/artikel | grep -i "je belangrijkste heading"
# Simuleer een specifieke AI-crawler
curl -s -H "User-Agent: GPTBot/1.0" https://jouwsite.nl/blog/artikel | head -100
Als je heading en body-tekst in de curl-output staan, kunnen AI-crawlers het lezen. Staat er alleen een lege
of
, dan heb je een CSR-probleem.
Je kunt ook in je browser "Paginabron weergeven" gebruiken (Ctrl+U). Dit toont de ruwe HTML, niet de gerenderde DOM. Als je content daar niet zichtbaar is, is het ook onzichtbaar voor AI-bots.
Geautomatiseerde controle
Voor grotere sites kun je een script schrijven dat automatisch controleert of belangrijke pagina's volledige HTML teruggeven:
#!/bin/bash
# check-ssr.sh — Controleer of pagina's server-side gerenderd worden
URLS=(
"https://jouwsite.nl/blog/artikel-1"
"https://jouwsite.nl/blog/artikel-2"
"https://jouwsite.nl/diensten"
)
for url in "\${URLS[@]}"; do
CONTENT_LENGTH=$(curl -s "$url" | wc -c)
HAS_CONTENT=$(curl -s "$url" | grep -c "<article")
if [ "$HAS_CONTENT" -gt 0 ] && [ "$CONTENT_LENGTH" -gt 5000 ]; then
echo "OK: $url ($CONTENT_LENGTH bytes)"
else
echo "WAARSCHUWING: $url — mogelijk geen SSR ($CONTENT_LENGTH bytes)"
fi
done
Veelgemaakte fouten
- SPA zonder SSR deployen. React of Vue apps die puur client-side renderen. Lees meer hierover in ons artikel over GEO-fouten bij React SPA's zonder SSR.
- Dynamische content achter
useEffect of onMounted. Data die pas na mount wordt opgehaald, is onzichtbaar in de initiële HTML.
- Loading states als enige content. Als je HTML alleen "Laden..." bevat totdat JavaScript klaar is, is dat alles wat een AI-crawler ziet.
- API-routes zonder fallback. Als je content via een client-side API-call ophaalt zonder server-side fallback, is de content onzichtbaar.
Conclusie
Voor maximale AI-zichtbaarheid is de keuze helder: gebruik SSG waar mogelijk, ISR voor content die regelmatig verandert, en SSR als fallback voor zeer dynamische pagina's. Vermijd CSR voor elke pagina die je in AI-antwoorden wilt laten verschijnen.
De technische implementatie verschilt per framework, maar het principe is universeel: zorg dat je volledige content in de eerste HTML-response zit.
Wil je een breder overzicht van alle technische vereisten voor AI-zichtbaarheid? Bekijk dan onze Technische GEO-checklist. En als je al weet dat je SPA een probleem vormt, lees dan GEO-fouten bij React SPA zonder SSR.
Lees ook
Meet je AI-zichtbaarheid
Ontdek waar jouw bedrijf verschijnt in ChatGPT, Perplexity en andere AI-zoekmachines.
Probeer Briljant 7 dagen gratis