Technische SEO voor een webshop zorgt ervoor dat zoekmachines de juiste URL's van je winkel kunnen crawlen, renderen en indexeren, en begrijpen wat elke productpagina verkoopt. Het gaat over crawlsturing, JavaScript-rendering, indexregels per paginatype, sitestructuur, paginering, XML-sitemaps, gestructureerde data en laadsnelheid. Op een site van tien pagina's regelt veel daarvan zichzelf. Op een webshop niet, want elk product, elke variant, filter, sortering, paginanummer en taal vermenigvuldigt het aantal URL's dat een crawler kan vinden.
Deze gids is voor webshops die de basis al op orde hebben. Wil je eerst een complete controle, begin dan met de SEO-audit voor je webshop, en lees voor filters de gids over faceted navigation. Hier gaan we een laag dieper: hoe je meet wat Googlebot echt op je webshop doet, en hoe je regels per template opstelt die blijven werken als je assortiment verdubbelt.
De URL-inventaris: tel wat een crawler kan vinden voordat je iets aanpast
De meeste technische SEO-problemen in webshops zijn rekenwerk. Schrijf voordat je één tag aanpast op hoeveel URL's elk template kan opleveren. Neem een outdoorwinkel als voorbeeld:
- 4.200 producten, waarvan 1.300 met varianten, samen 11.000 variant-SKU's.
- 180 categorieën, elk met 5 filters, 4 sorteringen en 24 producten per pagina.
- 3 talen (Nederlands, Engels, Duits) in submappen.
- Variantkeuze via een ?variant=-parameter, interne zoekfunctie op /search?q=.
Alleen de producten geven al 12.600 product-URL's in drie talen. Variantparameters voegen er tot 33.000 aan toe als ze gelinkt worden. Categorieën met gemiddeld 3 pagina's geven 1.620 overzichts-URL's, en de 4 sorteringen maken daar 6.480 van voordat er één filter is aangeklikt. Combineer twee filters en je zit op zes cijfers. De webshop wil zo'n 14.200 URL's in de index: producten, categorieën en hun paginering, in drie talen.
Crawlbare URL's tegenover de URL's die de webshop geïndexeerd wil hebben
Voorbeeld ter illustratie| Categorie | URL's |
|---|---|
| Product-URL's, 3 talen | 12.600 |
| Variantparameter-URL's, als ze gelinkt zijn | 33.000 |
| Overzichts-URL's van categorieën | 1.620 |
| Overzichts-URL's met 4 sorteringen | 6.480 |
| Gewenste URL's in de index | 14.200 |
Dat verschil tussen mogelijke en gewenste URL's is het hele vak. Elke regel in de rest van deze gids zorgt dat ongewenste URL's niet gevonden worden, vertelt Google welke versie het moet indexeren, of maakt de gewenste URL's makkelijker bereikbaar en begrijpelijk.
Serverlogs laten zien wat Googlebot echt opvraagt
Een crawler zoals Screaming Frog laat zien wat vanaf de homepage te vinden is. Je serverlogs laten zien wat Googlebot echt heeft opgehaald, hoe vaak en met welke statuscode. In een webshop is dat zelden hetzelfde. Vraag je hostingpartij of platform om ruwe access logs van minimaal 30 dagen, filter op de Googlebot-user-agent en gooi hits weg die een reverse DNS-check niet halen, want veel scrapers doen zich voor als Googlebot.
Groepeer daarna elk verzoek per template, op basis van URL-patronen die je al kent (/products/, /collections/, ?sort=, ?page=, /search). De nuttige vragen zijn eenvoudig:
- Aandeel verzoeken per template. Gaan 40% van de Googlebot-hits naar sorteer- en filter-URL's en maar 25% naar producten, dan gaat de crawlactiviteit naar de verkeerde plek.
- Dagen sinds de laatste crawl per product. Producten die Googlebot 30 dagen niet heeft opgevraagd, tonen in Google oude prijzen en voorraad.
- Statuscodes per template. Veel 301's op product-URL's betekent meestal dat interne links nog naar oude URL's wijzen.
- Nooit gecrawlde producten. Producten uit je catalogusexport die in 30 dagen logs niet voorkomen, zijn in de praktijk onzichtbaar.
Kun je geen logs krijgen, dan is het rapport Crawlstatistieken in Search Console de beste vervanger. Het splitst verzoeken uit naar statuscode, bestandstype, type Googlebot en doel, waarbij ontdekking een URL is die Google nooit eerder crawlde en vernieuwing een nieuwe crawl van een bekende pagina. Lanceer je 300 nieuwe producten per week en zie je bijna geen ontdekkingsverzoeken, dan zit het probleem meestal in je sitemaps of interne links.
Crawlverspilling in een webshop: soft 404's, redirectketens en noindex
Googles gids over crawlbudget is geschreven voor sites met 1 miljoen of meer unieke pagina's die ongeveer wekelijks veranderen, of 10.000 of meer pagina's die dagelijks veranderen. Een webshop met 4.200 producten zit onder beide grenzen, maar filter- en sorteercombinaties kunnen het aantal crawlbare URL's er ver boven duwen, en door prijs- en voorraadwijzigingen veranderen productpagina's dagelijks. Behandel crawl-efficiëntie dus als een echte beperking zodra je logs laten zien dat Googlebot de meeste tijd buiten je gewenste URL's doorbrengt.
Dezelfde gids noemt wat crawls verspilt, en in webshops ziet dat er zo uit:
- Soft 404's. Een uitverkochte productpagina met de tekst "niet meer leverbaar" en een 200-status blijft gecrawld worden. Geef een echte 404 of 410 voor producten die weg zijn, of stuur door naar een goede opvolger.
- Lange redirectketens. Een product dat drie keer is hernoemd, zit soms achter drie stappen. Laat interne links en sitemapregels direct naar de eind-URL wijzen.
- noindex als crawlbespaarder. Google vraagt een pagina met noindex nog steeds op en laat hem daarna vallen, dus noindex bespaart geen crawls. Gebruik robots.txt voor URL-patronen die je nooit gecrawld wilt hebben, zoals sorteringen en interne zoekresultaten.
- Geen lastmod. Google leest sitemaps regelmatig. Een kloppende <lastmod> bij gewijzigde producten helpt bepalen wat opnieuw gecrawld wordt.
- Geen 304-ondersteuning. Servers die 304 Not Modified teruggeven voor ongewijzigde pagina's laten Google zijn eigen kopie hergebruiken. Dat scheelt als duizenden productpagina's sinds het vorige bezoek niet veranderd zijn.
Ook de gezondheid van je server telt. Geeft de webshop 5xx-fouten of 429-limieten, dan gaat Google langzamer crawlen en versnelt het pas geleidelijk weer. Een traag categorietemplate tijdens de sale kan je dan precies de nieuwe crawls kosten van producten die je net hebt afgeprijsd.
Rendering: wat Googlebot ziet voor en na JavaScript
Google verwerkt JavaScript-sites in drie fasen: crawlen, renderen en indexeren. Volgens Googles uitleg over JavaScript-SEO gaat elke pagina met een 200-status in een renderwachtrij, waar hij een paar seconden of langer kan wachten. Voor webshops heeft dat twee gevolgen. Ten eerste ontdekt Google alleen links die <a>-elementen met een href zijn, dus een carrousel met gerelateerde producten die op klik-events draait, geeft geen links door. Ten tweede komt alles wat pas na het renderen bestaat later binnen dan wat in de HTML staat.
Dat tweede punt is belangrijk voor productdata. Google zegt dat Product-markup die met JavaScript wordt gegenereerd Shopping-crawls minder frequent en minder betrouwbaar kan maken, en dat is een probleem voor snel veranderende gegevens zoals prijs en beschikbaarheid. Zet je thema of headless frontend de Product-JSON-LD pas na een API-call in de pagina, verplaats hem dan naar de server-side HTML.
Een snelle test per template: open de paginabron (niet de inspector) en zoek naar de productnaam, de prijs, de GTIN en de eerste twee categorielinks. Draai daarna URL-inspectie in Search Console en vergelijk met de gerenderde HTML. Alles wat in de bron ontbreekt maar na het renderen wel bestaat, is afhankelijk van de renderwachtrij.
- Moet in de server-HTML staan: title-tag, canonical, robots-meta, H1, prijs, beschikbaarheid, Product-JSON-LD, breadcrumb-links, links naar producten op categoriepagina's, pagineringslinks.
- Mag client-side laden: reviewwidgets onder de vouw, recent bekeken producten, gepersonaliseerde aanbevelingen, chat.
Indexregels per template, één keer vastgelegd voor de hele catalogus
Beslissingen per URL schalen niet. Leg per template één regel vast en dwing die af in de thema- of platforminstellingen. Voor de outdoorwinkel ziet dat er zo uit:
Indexregels per template voor de outdoorwinkel
| Productpagina | Indexeren | Naar zichzelf | Ja |
|---|---|---|---|
| Variant-URL (?variant=) | Alleen apart indexeren als elke variant eigen content en zoekvraag heeft | De product-URL als varianten één pagina delen | |
| Categoriepagina 1 | Indexeren | Naar zichzelf | Ja |
| Categoriepagina 2 en verder | Indexeren | Naar zichzelf | Nee |
| Sorteer-URL's | Geblokkeerd in robots.txt, nooit als gewone link | ||
| Filter-URL's | Alleen vooraf gekozen combinaties krijgen een vaste URL en worden geïndexeerd; de rest volgt je regels voor faceted navigation | ||
| Interne zoekresultaten | Geblokkeerd in robots.txt | ||
| Tijdelijk uitverkocht product | Blijft geïndexeerd met availability OutOfStock | ||
| Product uit het assortiment | 301 naar een opvolger of de best passende categorie als die er is, anders 404 of 410 | ||
| Winkelwagen, account, checkout, vergelijken | Geblokkeerd in robots.txt | Nooit |
Regels per veld, zoals titels, beschrijvingen en afbeeldingen, staan in de gids over SEO voor productpagina's. Instellingen per platform vind je in de Shopify SEO-checklist en de gids over Magento SEO-instellingen.
Sitestructuur voor grote catalogi: klikdiepte, hubs en weesproducten
De structuur bepaalt hoe snel een crawler bij een product komt en hoeveel interne linkwaarde het krijgt. In een webshop linkt het menu naar categorieën, categorieën linken naar producten, en producten linken opzij naar gerelateerde producten en terug omhoog via breadcrumbs. Drie controles houden die structuur gezond als het assortiment groeit:
- Klikdiepte. Crawl vanaf de homepage en tel het aantal klikken naar elk product. Linken overzichtspagina's alleen naar de volgende pagina, dan staat een product op pagina 6 van een categorie met 140 producten 7 klikken van de homepage. Splits je die categorie in vier subcategorieën van 35 producten, dan is dat nog 4 klikken.
- Categoriegrootte. Een categorie met 1.200 producten en 24 per pagina heeft 50 pagina's, en de producten op de laatste pagina's worden het minst gecrawld. Subcategorieën op basis van echte attributen (type isolatie, vulgewicht) maken die staart korter en geven je landingspagina's voor echte zoekopdrachten.
- Weesproducten. Vergelijk de URL's in je productexport met de URL's die een crawler heeft bereikt. Producten die wel in de export staan maar niet in de crawl, hebben geen interne links: vaak producten zonder categorie, of alleen in een categorie die uit het menu verborgen is.
Weesproducten zijn meestal een productdataprobleem, geen themaprobleem. Een product met een leeg categorieveld verschijnt nooit op een overzichtspagina. Herstel eerst de categorie-indeling in je catalogus en controleer daarna of het template de link als crawlbare <a href> toont.
Paginanummers, knoppen voor meer laden en infinite scroll
Googles richtlijnen voor paginering in webshops zijn kort en concreet. Geef elke pagina een eigen URL, bijvoorbeeld ?page=2. Zet pagina 1 niet als canonical voor de hele reeks, want dan zeg je dat pagina 2 en verder duplicaten zijn en verliezen de producten daarop een route om ontdekt te worden. Link de pagina's aan elkaar met gewone <a href>-links. Google gebruikt rel="next" en rel="prev" niet meer, al kunnen andere zoekmachines dat wel doen.
Een knop "meer laden" en infinite scroll vragen extra aandacht. De crawlers van Google klikken niet op knoppen en voeren in het algemeen geen JavaScript uit dat een actie van de gebruiker nodig heeft. Gebruik je infinite scroll, houd dan een gepagineerde versie met echte links achter de hand, en zorg dat elk product ook in je XML-sitemap of een Merchant Center-feed staat, zodat het zonder de overzichtspagina gevonden kan worden.
Twee tips specifiek voor webshops: kies een paginagrootte waarbij de meeste categorieën onder de vijf pagina's blijven, en zet paginanummers nooit achter een #-fragment, want Google negeert alles na de #.
XML-sitemaps die je uit je productdata opbouwt
Een sitemap is een lijst van de URL's die je in Google wilt hebben. In een webshop bouw je hem op uit de catalogus, niet uit een crawl. Googles documentatie over sitemaps geeft de grenzen en regels:
- Een sitemap bevat maximaal 50.000 URL's of 50 MB ongecomprimeerd. Combineer meerdere bestanden met een sitemapindex.
- Gebruik absolute URL's en neem alleen canonieke URL's op, dus de versie die je in de zoekresultaten wilt zien.
- Google negeert <priority> en <changefreq>, dus besteed daar geen tijd aan.
- Google gebruikt <lastmod> alleen als die consequent klopt. Pas hem aan bij betekenisvolle wijzigingen in de hoofdcontent, gestructureerde data of links, niet voor een nieuw copyrightjaar.
Splits sitemaps per template en taal, bijvoorbeeld products-nl.xml, products-de.xml en categories-nl.xml. Search Console rapporteert dan per bestand, zodat je ziet dat 96% van je Nederlandse producten geïndexeerd is en maar 61% van de Duitse. Laat doorgestuurde, noindex-, gecanonicaliseerde en verwijderde URL's weg. En stuur <lastmod> aan vanuit het productrecord: een prijswijziging verandert de Offer-markup en telt dus als wijziging in de gestructureerde data.
Gestructureerde data op schaal: genereer ze uit de catalogus, niet uit het thema
De meeste webshops zetten Product-markup in de pagina via een thematemplate. Dat werkt tot de data erachter onvolledig is of de varianten ingewikkeld worden. Bij een groot assortiment behandel je gestructureerde data als een export van je productdata en controleer je ze zoals je een feed controleert.
Voor varianten ondersteunt Google ProductGroup-markup. Het hoofdproduct krijgt een productGroupID (de parent-SKU), variesBy noemt de eigenschappen die verschillen, en hasVariant somt elke variant op als Product. Toegestane waarden voor variesBy zijn color, size, suggestedAge, suggestedGender, material en pattern. Er zijn twee opzetten:
- Eén pagina: alle varianten staan op één pagina, met één canonieke URL voor de groep. Elke variant heeft wel een eigen URL nodig die hem voorselecteert, meestal met een queryparameter.
- Meerdere pagina's: elke variant heeft een eigen pagina met volledige, op zichzelf staande markup. Er is dan geen enkele canonieke URL voor de groep.
Neem een donsjas in 3 kleuren en 5 maten: 15 varianten, elk met een eigen GTIN, prijs en voorraad. Leest het template kleur en maat van het hoofdproduct, dan melden alle 15 variantobjecten dezelfde waarden en ziet Google duplicaten. Zijn 4 van de 15 GTIN's leeg, dan gaan die varianten zonder identificatie de deur uit. Geen van beide problemen zie je in een themavoorbeeld, en beide los je op in de data, niet in de markup.
Praktische controles op schaal: valideer één URL per template met de Test voor uitgebreide resultaten en houd daarna de rapporten Verkopersvermeldingen en Productfragmenten in Search Console in de gaten voor fouten op veel URL's tegelijk. Tel lege GTIN-, merk-, kleur- en maatwaarden per categorie in je catalogus voordat je het template de schuld geeft. Wil je een referentievoorbeeld om je output mee te vergelijken, gebruik dan de productschema-generator.
LCP-afbeeldingen, layout shift en appscripts op catalogustemplates
Snelheidsproblemen in webshops herhalen zich per template. Meet dus één productpagina en één categoriepagina per templatetype op een gemiddelde telefoon en los het op in het template. De productfoto is meestal het Largest Contentful Paint-element. Laad hem nooit lazy, zorg dat hij in de HTML-bron vindbaar is in plaats van via JavaScript toegevoegd, en geef hem fetchpriority="high". Splits een trage LCP op in de onderdelen (serverrespons, laadvertraging, laadtijd en rendervertraging) voordat je een snellere hosting koopt, want de vertraging is vaak een script dat draait voordat de afbeelding wordt opgevraagd.
Layout shift op categorie- en productpagina's komt vaak uit de data: afbeeldingen zonder breedte en hoogte, kleurstalen die na de prijs laden, een label "bijna uitverkocht" dat de bestelknop omlaag duwt. Sla de afmetingen van afbeeldingen op bij het afbeeldingsrecord, zodat het template ruimte kan reserveren. Vertraging bij interactie komt meestal van filterscripts en apps van derden. Zet dus elk script op een categoriepagina op een lijst met de app die het laadt, en verwijder wat niemand gebruikt.
Een vaste technische SEO-routine per kwartaal voor een groeiend assortiment
Technische SEO-routine per kwartaal
Een deel van deze controles begint in de catalogus en niet in de code. De sitemapdekking in WISEPIM-analytics koppelt je sitemap-URL's aan productrecords, en de analyse van interne links toont weesproducten naast hun Search Console-data. Omdat WISEPIM GTIN's, categorieën en variantattributen compleet houdt voordat ze naar je webshop gaan, blijven de gestructureerde data en sitemaps die op die data draaien kloppen als het assortiment groeit.

