JavaScript-SEO bij headless webshops: CSR, SSR en hydration
Terug naar blog

JavaScript-SEO bij headless webshops: CSR, SSR en hydration

7 min leestijd

Een headless webshop kan prima ranken, mits de belangrijke content al in de HTML staat die de server terugstuurt.

Een headless webshop kan prima ranken, mits de belangrijke content al in de HTML staat die de server terugstuurt. Bij pure client-side rendering (CSR) moet Google je pagina eerst door zijn rendering queue halen voordat het producten, prijzen en links ziet, en veel andere crawlers, waaronder de meeste AI-crawlers, doen dat helemaal niet. Kies daarom voor server-side rendering (SSR) of statische generatie, en behandel hydration als een performancevraagstuk, niet als SEO-oplossing.

Wat er gebeurt als Google een JavaScript-pagina crawlt

Google verwerkt pagina's in drie stappen:

  1. Crawlen. Googlebot haalt de HTML op die je server terugstuurt.
  2. Renderen. De pagina gaat in een wachtrij voor de Web Rendering Service, die een actuele versie van Chromium gebruikt en JavaScript uitvoert.
  3. Indexeren. Google indexeert op basis van de gerenderde HTML.

Bij een server-gerenderde pagina staat alles al in stap 1. Links worden direct ontdekt, content kan direct beoordeeld worden. Bij een client-side gerenderde pagina is de HTML uit stap 1 vaak niet meer dan een lege

en een paar scriptbestanden. Alles hangt dan af van stap 2.

Google rendert tegenwoordig vrijwel elke pagina. Het probleem zit niet in óf Google rendert, maar in de voorwaarden:

  • Rendering kost tijd en rekenkracht. Hoe lang een pagina in de wachtrij staat, maakt Google niet per site bekend. Voor een shop met snel wisselende prijzen en voorraad is elke vertraging nadelig.
  • Rendering kan mislukken. Timeouts, API-calls die falen, scripts die geblokkeerd zijn in robots.txt, of een consentbanner die de content afschermt.
  • Links worden later ontdekt. Als je categorieën alleen via JavaScript naar producten linken, vindt Google die producten pas na rendering.

Andere crawlers renderen niet

Hier zit het grootste risico van CSR anno nu. Google rendert, maar Google is niet de enige die je shop leest.

  • AI-crawlers. Voor zover publiek bekend voeren de crawlers van OpenAI (GPTBot, OAI-SearchBot), Anthropic (ClaudeBot) en Perplexity (PerplexityBot) in de regel geen JavaScript uit. Wat niet in de ruwe HTML staat, zien ze dus niet. Een productpagina die pas na JavaScript een titel en prijs toont, is voor die systemen een lege pagina.
  • Social previews. Facebook, LinkedIn, WhatsApp en Slack lezen Open Graph-tags uit de ruwe HTML.
  • Vergelijkers en feeds die pagina's scrapen in plaats van een feed te gebruiken.
  • Bing rendert ook JavaScript, maar dat is geen reden om erop te vertrouwen. ChatGPT search gebruikt onder meer de Bing-index.

Wil je zichtbaar zijn in AI-zoekmachines, dan moet je productinformatie zonder JavaScript leesbaar zijn. Meer daarover op onze pagina over GEO voor webshops.

CSR, SSR, SSG en ISR naast elkaar

AanpakWat de crawler krijgtGeschikt voor
CSR (client-side rendering)Lege HTML, content na JavaScriptAccount, checkout, dashboards
SSR (server-side rendering)Volledige HTML per requestCategorieën en producten met wisselende prijs en voorraad
SSG (static site generation)Vooraf gebouwde HTMLContentpagina's, blogs, kleine catalogi
ISR / revalidatieStatische HTML die periodiek of op aanvraag ververstGrote catalogi waar volledige rebuilds te traag zijn

De vuistregel: alles wat moet ranken, wordt op de server gerenderd. Alles achter een login mag client-side. Een uitgebreidere vergelijking voor productpagina's staat in SSR vs SSG voor productpagina's.

Dynamic rendering is geen oplossing meer

Dynamic rendering betekent dat je crawlers een vooraf gerenderde versie geeft en gebruikers de CSR-versie. Google noemt dit expliciet een workaround en raadt het niet aan als langetermijnoplossing. Je onderhoudt twee versies van je site, en elk verschil tussen die versies is een bron van fouten.

Hydration: waar SEO en performance elkaar raken

Bij SSR stuurt de server complete HTML. Daarna laadt de browser JavaScript dat die HTML "tot leven wekt": event handlers koppelen, state opbouwen, interactieve componenten activeren. Dat heet hydration.

Voor SEO is hydration op zich geen probleem, want de content stond er al. Voor performance wel:

  • INP. Tijdens hydration is de main thread bezig. Klikt een bezoeker op dat moment op een filter of "in winkelwagen", dan reageert de pagina traag. INP moet op het 75e percentiel onder 200 ms blijven.
  • LCP. Wordt je hoofdafbeelding pas door JavaScript ingeladen, of is hij afhankelijk van een client-side API-call, dan schuift LCP op. De drempel is 2,5 seconde.
  • CLS. Content die na hydration anders wordt opgebouwd dan de server-HTML, verschuift de layout.

Hydration mismatches

Een hydration mismatch ontstaat als de HTML van de server afwijkt van wat de client rendert. Klassieke oorzaken in webshops:

  • Prijzen die op de server zonder btw en in de browser met btw worden berekend.
  • Voorraad of levertijd die client-side opnieuw wordt opgehaald.
  • Datum- en tijdnotatie die van de tijdzone afhangt.
  • Personalisatie of A/B-tests die in de browser de content vervangen.

Het gevolg kan zijn dat de bezoeker en Google andere content zien, of dat het framework de hele boom opnieuw rendert. Beide wil je niet.

Moderne aanpakken beperken hydration tot de onderdelen die interactief moeten zijn. Denk aan React Server Components in Next.js, of het islands-patroon in frameworks als Astro. Hoe minder JavaScript er moet hydrateren, hoe beter je INP.

Per platform

Magento PWA Studio

PWA Studio is Adobe's React-gebaseerde frontend voor Magento, gekoppeld via GraphQL. In de standaardopzet wordt veel client-side gerenderd. Wil je hiermee goed ranken, dan moet je zelf zorgen dat categorie- en productpagina's server-side of vooraf worden gerenderd, met de juiste meta-tags, canonicals en structured data in de initiële HTML. Dat is extra werk dat bij een klassieke Magento-frontend niet nodig is.

Hyvä

Hyvä is geen headless frontend. Het is een Magento-thema dat de pagina's op de server rendert als gewone HTML, met Alpine.js voor interactie en Tailwind voor styling. Crawlers krijgen dus direct de volledige content. De hoeveelheid JavaScript is veel kleiner dan bij Luma, wat goed is voor INP en LCP.

Voor veel Magento-shops die naar "headless" kijken vanwege snelheid, is Hyvä daarom de eenvoudigere route: de performancewinst zonder de JavaScript-SEO-risico's. Meer op onze Hyvä-pagina.

Next.js (met Magento, Shopify of een ander backend)

Next.js ondersteunt SSR, SSG en revalidatie per route. Dat maakt het een goede keuze voor headless, mits je het goed inricht:

  • Gebruik server-rendering voor categorie- en productroutes, niet useEffect om productdata op te halen.
  • Zet metadata via de metadata-API van het framework, zodat title, description en canonical in de server-HTML staan.
  • Render JSON-LD op de server, niet via een client-side script dat het later injecteert.
  • Gebruik de Link-component, die rendert als een echte .

Shopify Hydrogen

Hydrogen is Shopify's eigen React-framework voor headless storefronts en rendert standaard op de server. Daarmee heb je de basis goed. Je verliest wel een deel van wat een Liquid-thema automatisch regelt, zoals canonicals, sitemaps en een deel van de structured data. Die moet je zelf inbouwen.

De checklist voor een headless webshop

Loop deze punten na op een categorie- en productpagina:

  1. Bekijk de ruwe HTML met curl of "Paginabron weergeven", niet met de element-inspector. Staan producttitel, prijs, beschrijving en interne links erin?
bash
curl -s -A "Mozilla/5.0 (compatible; Googlebot/2.1)" https://www.voorbeeldshop.nl/product/x | grep -i "<title>\|canonical\|application/ld+json"
  1. Echte links. Navigatie, filters die je wilt laten crawlen en paginering gebruiken . Geen onClick-handlers op divs, geen hash-URL's (/#/product/x), want het deel na de # wordt niet als aparte URL geïndexeerd.
  2. Statuscodes. Een niet-bestaand product geeft een echte 404 terug vanaf de server. Een SPA die altijd 200 teruggeeft en client-side "niet gevonden" toont, levert soft 404's op.
  3. Meta en canonical in de server-HTML. Niet via JavaScript achteraf aanpassen. Google kan een via JavaScript gewijzigde canonical oppikken, maar tegenstrijdige signalen tussen ruwe en gerenderde HTML wil je vermijden.
  4. Structured data in de server-HTML. Product, Offer en BreadcrumbList.
  5. Robots.txt blokkeert geen JS- of API-bestanden die nodig zijn om de pagina te renderen.
  6. URL-inspectie in Search Console. Vergelijk de gerenderde HTML met wat je verwacht.
  7. Field data. Meet LCP, INP en CLS bij echte gebruikers. Lighthouse-scores zijn labdata en zeggen weinig over hoe hydration uitpakt op een middenklasse-telefoon.

Meer over de performancekant op onze pagina over Core Web Vitals, en de bredere technische basis op technische SEO voor webshops.

Moet je wel headless gaan?

De eerlijke versie: headless lost geen SEO-probleem op. Het verplaatst een deel van het werk van het platform naar jouw team. Canonicals, redirects, sitemaps, structured data, hreflang en foutpagina's moet je zelf bouwen en onderhouden.

Headless kan zinvol zijn als je meerdere frontends op één backend draait, of een sterk afwijkende gebruikerservaring wilt. Gaat het vooral om snelheid, dan haal je die vaak met minder risico uit een snel server-gerenderd thema.

Veelgestelde vragen

Kan Google JavaScript-websites indexeren?

Ja. Google rendert pagina's met een actuele versie van Chromium. Rendering gebeurt wel in een aparte stap na het crawlen, kan vertraging opleveren en kan mislukken. Content die direct in de server-HTML staat, is betrouwbaarder.

Lezen AI-crawlers JavaScript?

Voor zover publiek bekend voeren de meeste AI-crawlers, zoals GPTBot, ClaudeBot en PerplexityBot, geen JavaScript uit. Ze lezen de ruwe HTML. Productinformatie die pas na JavaScript verschijnt, is voor hen dus onzichtbaar.

Is Hyvä een headless oplossing?

Nee. Hyvä is een Magento-thema dat pagina's op de server rendert, met Alpine.js voor interactie. Crawlers krijgen direct volledige HTML. Je houdt de SEO-functionaliteit van Magento en wint snelheid ten opzichte van Luma.

Wat is een hydration mismatch?

Een verschil tussen de HTML die de server stuurt en wat de browser na het laden van JavaScript rendert. Het kan zorgen voor andere content voor bezoeker en crawler, layoutverschuivingen en extra rekenwerk in de browser.

Is dynamic rendering nog een goede oplossing?

Nee. Google noemt dynamic rendering een tijdelijke workaround en raadt het niet aan. Kies voor server-side rendering, statische generatie of een combinatie daarvan.

Ruthger Idema

Geschreven door Ruthger Idema

15+ jaar ervaring in e-commerce development. Gespecialiseerd in Magento, Shopify en Laravel maatwerk.

Meer over ons team →
Deel dit artikel:

Wil je jouw e-commerce naar het volgende niveau?

Plan een vrijblijvend gesprek met onze experts over Magento, Shopify of Laravel maatwerk.

Plan een Tech Check