Kort gezegd: Shopping- en PMax-rapporten tonen de zoekopdracht maar verbergen het product. Voeg één URL-parameter toe — {lpurl}?utm_content={product_id} — en binnen een week levert GA4 je het afgeschafte zoekopdracht × product-rapport door sessionManualAdContent te koppelen aan sessionGoogleAdsQuery. Op een echt account legde dit bloot dat 85 % van de uitgaven door nul-converterende paren liep en dat een schijfje van 0,25 % het hele account draagt op 46,8× ROAS.
Voeg één URL-parameter toe aan je Shopping- en Performance Max-campagnes en binnen een week levert GA4 je het rapport dat Google stilletjes heeft afgeschaft: elke betaalde klik gekoppeld als zoekopdracht × product — met sessies, conversies en omzet eraan vast. Juist in die koppeling zit het geld verstopt — welke producten rommeltraffic trekken, welke titels echte vraag missen, welke zoekopdrachten budget verbranden en nooit verkopen. De bouw is die ene parameter; de rest van dit artikel gaat over wat je doet met wat terugkomt.
Als je Shopping- of Performance Max-campagnes draait, ken je het zoekopdrachtenrapport. Wat je misschien niet hebt opgemerkt — omdat Google er nooit op wijst — is wat erin ontbreekt: het product.
Je ziet dat iemand zocht op “steelstofzuiger onder 200”. Je ziet klikken en kosten. Je ziet niet welk van je 5.000 producten die zoekopdracht triggerde, waar die op landde of wat verkocht werd.
Jaren geleden gaf de AdWords API je deze koppeling wel. Vandaag niet meer. En voor een e-commerce-account is dat geen cosmetisch gat — zoekopdracht-naar-product is waar de echte optimalisatie zit: of je titels echte vraag dekken, welke producten rommeltraffic aantrekken, waarom een product klikken krijgt maar nooit converteert.
Voordat je het vraagt: nee, hier is geen instelling voor. Geen rapport, geen API-veld, geen script dat het terugbrengt vanaf Google’s kant. Je moet het zelf herbouwen — en die herbouw is bijna gênant eenvoudig.
De oplossing: één parameter, twee GA4-dimensies
Voeg een trackingsjabloon toe
Op je Shopping- en PMax-campagnes: {lpurl}?utm_content={product_id}. De ValueTrack-variabele {product_id} stuurt de Merchant Center product-ID mee met elke klik.
GA4 bewaart het product
De UTM landt in de dimensie Session manual ad content (sessionManualAdContent).
GA4 kent de zoekopdracht al
Auto-tagging (gclid) vult sessionGoogleAdsQuery op dezelfde sessie.
Koppel de twee dimensies
Elke betaalde klik wordt een zoekopdracht × product-paar — met sessies, conversiepercentage en omzet eraan vast.
Auto-tagging en de handmatige UTM vechten niet met elkaar: gclid blijft bron, medium en campagne afhandelen; jouw UTM draagt alleen de product-ID.
Weet wat je krijgt (en wat niet)
- Alleen geklikte zoekopdrachten. Deze dataset begint bij de klik. Zoekopdrachten waarvoor je advertentie verscheen maar niemand klikte, bereiken GA4 nooit — analyse op vertoningsniveau blijft in Google’s standaardrapport (zonder producten).
- ~20 % van de klikken matcht niet: consent-geweigerde sessies, PMax-oppervlakken zonder enige zoekopdracht (Display, YouTube, Gmail), klikken die nooit analytics afvuurden.
- Sessiegebonden. Eén sessie = één product-ID — die van de klik, ook als de gebruiker daarna nog tien andere bekijkt.
Het rapport uit GA4 trekken
In de UI: Verkennen → vrije vorm. Dimensies: Session manual ad content + Session Google Ads query. Statistieken: sessies, conversies, aankoopomzet. Filter: sessiebron/-medium = google / cpc.
Via de Data API — voor iets serieus voedt dit een dashboard of een BigQuery-join:
from google.analytics.data_v1beta import BetaAnalyticsDataClient
from google.analytics.data_v1beta.types import (
RunReportRequest, DateRange, Dimension, Metric, FilterExpression, Filter
)
request = RunReportRequest(
property=f"properties/{GA4_PROPERTY_ID}",
dimensions=[
Dimension(name="sessionManualAdContent"), # product ID
Dimension(name="sessionGoogleAdsQuery"), # search term
],
metrics=[
Metric(name="sessions"),
Metric(name="conversions"),
Metric(name="purchaseRevenue"),
],
date_ranges=[DateRange(start_date="30daysAgo", end_date="today")],
dimension_filter=FilterExpression(filter=Filter(
field_name="sessionSourceMedium",
string_filter=Filter.StringFilter(value="google / cpc"),
)),
)
Koppel sessionManualAdContent aan je product feed (id → titel, prijs, categorie) en het rapport is compleet: zoekopdracht × product × titel × economie.
Geverifieerd, niet getheoretiseerd
We rolden dit uit op een live account — een Tsjechische elektronicaretailer met 22 ingeschakelde Shopping-campagnes — en checkten GA4 zeven dagen later:
GA4, 7 dagen na uitrol
- Rijen google/cpc-traffic 9.753
- Droeg de product-ID (utm_content) 96 %
- Droeg de zoekopdracht (sessionGoogleAdsQuery) 81 %
- Droeg beide — een werkend zoekopdracht × product-rapport 78 %
Nu het leuke deel: wat de paren je vertellen
1 · Het titelgat
Zet de zoekopdrachten naast de titel en beschrijving die ze triggerden. De mismatch springt eruit:
De feed-roadmap schrijft zichzelf. En dit is waar AI feed-verrijking ophoudt een sprong in het diepe te zijn en een meetbare loop wordt: herschrijf de titel rond de vraag die je net hebt bewezen, en kijk dan hoe CTR en conversiepercentage per zoekopdracht bewegen.
2 · Wie er nog meer op “jouw” zoekopdracht zit — en met welk product
Eén ding dat je niet kunt: uitgesloten zoekwoorden per product toevoegen. Google geeft je zo’n hendel niet in Shopping of PMax. Dus als een zoekopdracht × product-paar onderpresteert, is de vraag niet “hoe sluit ik het uit” — maar “waarom presteert het onder”.
Neem de zoekopdracht en scrape de live resultatenpagina ervoor. Concreet: DataForSEO, endpoint serp/google/organic/live/advanced — één POST met de zoekopdracht-tekst en de location_code van je markt, en je krijgt de hele resultatenpagina terug als gestructureerde JSON: betaalde advertenties, shoppingblokken met merchantnamen en prijzen, organisch eronder. Tegen ~$0,0035 per zoekopdracht kost het checken van 200 zoekopdrachten ongeveer $0,70.
Een typische bevinding: je middenklasse slaapzak verzamelt klikken op een generieke zoekopdracht — en dezelfde zoekopdracht toont drie budgetmerken in dezelfde categorie tegen de helft van jouw prijs. Je product is niet slecht; het is op prijs overklast in die specifieke veiling.
Nu heb je echte opties: herprijzen; het onderscheidende kenmerk in de titel zetten (“donsvulling, −15 °C comfort”); het product verplaatsen naar een campagne met een biedstrategie die past bij de marge-realiteit; of de zoekopdracht accepteren als upper-funnel en hem beoordelen op assisterende statistieken in plaats van last click.
3 · Structuur- en biedbeslissingen
Producten die zoekopdrachten met hoge intentie aantrekken, verdienen hun eigen componentengroepen en budgetten. Producten die alleen generieke traffic verzamelen, horen in restgroepen met conservatieve targets. Dit rapport is de bewijsbasis voor shopping-segmentatie — geen onderbuikgevoel.
4 · Een gezondheidscheck voor PMax
PMax vertelt je vrijwel niets over zoeken. Dit rapport is het dichtste wat je krijgt bij een audit van wat PMax daadwerkelijk voor je inkoopt op het zoekoppervlak — per product.
Kijk hoe ik één echte export doorloop, stap voor stap
Alles hierboven is het waarom. Hier is het hoe het er echt uitziet — elke stap, wat je downloadt, waar je naar staart en het echte getal dat terugkomt.
De data is een tweede account: een andere middelgrote Tsjechische webshop (niet de elektronicaretailer uit het GA4-blok hierboven — ik gebruik die omdat het assortiment breed genoeg is dat elk patroon op volle schaal zichtbaar wordt). Ik trok het ruwe Shopping-zoekopdrachtenrapport via de Google Ads API in een lokale SQLite-tabel en draaide de aggregaties hieronder. Eerst één kanttekening: dit ruwe rapport geeft je de advertentiegroep / productgroep waaronder de zoekopdracht werd geserveerd, niet het individuele product. Dat is precies het gat dat de UTM-truc dicht — maar zelfs op productgroepniveau zijn de tussentijdse uitkomsten luid genoeg om het punt te maken.
Bron voor elk getal in deze sectie: Google Ads Shopping-zoekopdrachtenrapport, één middelgroot Tsjechisch webshopaccount, ~22,6M regels, data getrokken april 2026.
Stap 1 · Trek het ruwe rapport en meet de berg
Wat je doet: exporteer het Shopping-zoekopdrachtenrapport via de Google Ads API (search_term_view) naar een lokale tabel — SQLite of BigQuery, alles waarop je een GROUP BY kunt draaien. Waarom dit eerst: voordat je iets koppelt, moet je voelen hoe groot en hoe luidruchtig de ruwe berg is. Dat ene feit reset elke verwachting die volgt.
Draai een simpele COUNT(*) en een paar SUM’s en dit is wat landt:
De ruwe berg — één COUNT, drie SUM's
- Rapportregels (zoekopdracht × productgroep) 22.640.716
- Unieke zoekopdrachten 5.370.131
- Productgroepen waaronder ze werden geserveerd 10.393
- Uitgaven / omzet (blended ROAS 6,8×) 2,57M / 17,4M CZK
Wat je hebt: 22,6 miljoen regels, 5,4 miljoen unieke zoekopdrachten. Geen mens leest dat. De enige taak van dat getal is je de volgende zet aanwijzen — klap deze berg in langs de dimensie die de rekeningen betaalt — en je waarschuwen dat handmatige triage per regel hopeloos is.
Stap 2 · Gooi 96 % weg vóór je iets analyseert
Wat je doet: tel de regels met nul klikken en filter ze eruit. Waarom: het Shopping-zoekopdrachtenrapport logt elke zoekopdracht waarvoor je advertentie verscheen, waarvan op de meeste niemand klikte. Die regels met alleen vertoningen kunnen je niets kosten en niets converteren — het is ruis die de tabel angstaanjagend laat lijken.
Situatie: 22,6M rijen, je weet niet waar te beginnen. Actie:
WHERE clicks > 0. Resultaat: de tabel klapt in tot 738.444 regels — een werkbaar formaat.
De vertoningenvloed
- Regels met nul klikken (pure vertoningen) 21.902.272 — 96,7 %
- Regels die ooit een kroon kostten 738.444 — 3,3 %
Wat je hebt: 96,7 % van het angstaanjagende getal was nooit iets anders dan ruis. Je werkt nu met een tabel van 738K regels, niet 22,6M — en elke aggregatie hieronder draait op het deel dat echt geld uitgeeft.
Stap 3 · Stel de ene vraag die het account herkadert
Wat je doet: splits op de geklikte regels de uitgaven in “minstens één keer geconverteerd” versus “nooit geconverteerd”, en tel de kosten van elk op. Waarom: dit is het getal dat “het account is prima, ROAS is 6,8” omzet in “het meeste budget doet niets”. Het is de belangrijkste tussentijdse uitkomst — bereken het vóór elk optimalisatie-idee.
De nul-conversie-rem
- Rapportregels die nul keer converteerden 99,75 %
- Aandeel van totale uitgaven dat die regels opaten 85,5 %
- Uitgaven zonder enige conversie erachter 2,20M CZK (~€88k)
- Alleen van geklikte regels: aandeel met nul conversies 92,3 %
Wat je hebt: 85 % van het budget liep door zoekopdracht × productgroep-combinaties die nooit één keer converteerden. Dat is geen afrondingsfout die je later optimaliseert — het is de hoofdact. En je kon het alleen zien omdat je de zoekopdracht hebt ingeklapt langs waartegen die werd verkocht.
Stap 4 · Check of de verspilling een paar schurken is of de hele meute
Wat je doet: sorteer de geklikte regels op kosten, neem de top 1 % en top 10 %, en kijk hoeveel van de totale uitgaven ze vasthouden. Waarom: dit bepaalt je tactiek. Als een handjevol termen het budget verbrandt, pauzeer je die en ben je klaar. Als de verspilling dun verspreid is, is termen pauzeren zinloos — dan heb je structurele fixes nodig.
Waar de verspilde uitgaven écht zitten
- Top 1 % van geklikte regels op kosten 10,5 % van uitgaven
- Top 10 % van geklikte regels op kosten 29,8 % van uitgaven
Wat je hebt: de rem is long-tail, niet een paar overtreders — de top 1 % van dure regels houdt amper een tiende van de uitgaven vast. Dus 20 slechte termen pauzeren verandert niets. Dit is de data-onderbouwde reden om de structuur te fixen (welke producten in welke campagne op welk target) in plaats van individuele zoekopdrachten te jagen — en een herinnering dat Google je sowieso geen uitsluiting per product laat toevoegen.
Stap 5 · Ontdek waarom de long tail lekt: één zoekopdracht, veel producten
Wat je doet: tel voor elke zoekopdracht hoeveel verschillende productgroepen die werd geserveerd. Waarom: het verklaart de verspilling mechanisch. Shopping matcht een zoekopdracht tegen de signalen van je hele feed, niet tegen de relevantie van één product — dus één zoekopdracht lekt over ongerelateerde hoeken van je assortiment, en je betaalt voor elke misser.
Situatie: “anti-blafapparaat” blijft budget verbranden. Actie:
COUNT(DISTINCT ad_group)voor die term. Resultaat: het werd geserveerd onder 139 verschillende advertentie- / productgroepen voor 976 CZK en ~0 conversies. “lego technic” raakte er 300.
Zoekopdracht-spray over het assortiment
- Unieke termen geserveerd onder meer dan één productgroep 46,7 %
- Meeste productgroepen die één zoekopdracht bereikte 6.661
- "anti-blafapparaat" → groepen / kosten / conversies 139 / 976 CZK / ~0
Wat je hebt: bijna de helft van je zoekopdrachten is uitgesmeerd over meerdere productgroepen, en de ergste overtreders bereiken er duizenden. Dat is de motor van de nul-conversie-rem uit Stap 3 — en precies het ding dat je eindelijk kunt zien zodra elke klik zijn product-ID draagt.
Stap 6 · Bekijk de ergste mismatches — ze zijn absurd
Wat je doet: trek de duurste regels die nooit converteerden en lees de zoekopdracht naast de productgroep waartegen die werd verkocht. Waarom: de aggregaatgetallen overtuigen je spreadsheet; deze drie rijen overtuigen je baas. Ze zijn het menselijk leesbare gezicht van Stap 5.
| Zoekopdracht | Geserveerd onder productgroep | Klikken | Kosten | Conv. |
|---|---|---|---|---|
| hondentrainingsband | Handtassen | 97 | 270 CZK | 0 |
| anti-blafapparaat | Babyproducten | 76 | 239 CZK | 0 |
| lego technic | Verlichting | 70 | 169 CZK | 0 |
Een zoekopdracht voor een hondentrainingsband betaald onder je groep Handtassen. Een anti-blafapparaat verkocht tegen Babyproducten. De productgroep heeft niets met de zoekopdracht te maken — Google matchte op brede feedsignalen, incasseerde de klik en rekende je af. Met zoekopdracht × product zie je dit in één oogopslag; met Google’s standaardrapport nooit. (Illustratief voorbeeld — categorieën vertaald en geanonimiseerd.)
Stap 7 · Nu de beloning: de 0,25 % die het hele account betaalt
Wat je doet: keer Stap 3 om — isoleer alleen de regels die wel converteerden en tel hun kosten en omzet op. Waarom: dit is de reden waarom de hele exercitie ertoe doet. Zodra je de winnaars kunt scheiden van de rem, bescherm je de winnaars en verhonger je de rest.
Het schijfje dat zijn brood verdient
- Regels die converteerden (aandeel van alle regels) 57.209 — 0,25 %
- Wat ze kostten 372k CZK (~€14,9k)
- Wat ze opleverden 17,4M CZK (~€697k)
- ROAS op dat schijfje 46,8×
Wat je hebt: een kwart procent van de regels draait op 46,8× ROAS en draagt feitelijk het account; de andere 99,75 % trekt het blended cijfer omlaag naar 6,8×. Dat schijfje vinden, zijn budget beschermen en al het andere ervandaan structureren is het hele werk — en niets daarvan is mogelijk totdat elke regel het product draagt waartegen die werd verkocht. Dat is wat de één-parameter-UTM bovenaan dit artikel je oplevert.
Het sjabloon + de drie valkuilen
{lpurl}?utm_content={product_id}- Zet geen aangepaste parameter in utm_campaign. Google Ads saneert waarden van aangepaste parameters — je campagnenamen worden herschreven en de historische continuïteit van GA4 breekt. Stuur alleen
utm_content; auto-tagging doet de rest. - Pas dit alleen toe op INGESCHAKELDE Shopping- + PMax-campagnes. Zoeken heeft het niet nodig; gepauzeerde campagnes vervuilen alleen je wijzigingsgeschiedenis.
- API-valkuil: programmatisch uitrollen? Recente Google Ads API-versies lieten
client.get_type(“FieldMask”)vallen — importeer in plaats daarvanfield_mask_pb2.FieldMask.
FAQ
Werkt dit voor Performance Max?
Ja, voor het zoek-/shoppingoppervlak. Klikken vanaf Display, YouTube en Gmail dragen de product-ID maar geen zoekopdracht — verwacht dat die rijen een lege zoekopdrachtdimensie hebben.
Breekt de UTM mijn GA4-attributie?
Nee. Auto-tagging (gclid) blijft bron/medium/campagne afhandelen; je voegt alleen ad content toe. Wat het wél zou breken, is een aangepaste parameter in utm_campaign — doe dat niet.
Waarom maar 78 % dekking?
Consent mode, zoekopdrachtloze PMax-oppervlakken en analytics-blockers eten de rest op. 78 % is ruim voldoende voor elk gebruik hierboven — je leest patronen, je telt geen centen.
Kan ik zoekopdrachten zien waarvoor mijn advertentie verscheen maar niemand klikte?
Nee. Deze dataset begint bij de klik. Analyse op vertoningsniveau blijft in het standaard zoekopdrachtenrapport — zonder producten.
Werkt het patroon ook buiten Google — Bing, Sklik?
Ja, het is overdraagbaar: elk platform met een URL-sjabloon, een productmacro en een analytics-dimensie om die op te vangen. De specifieke macro’s verschillen per platform.
Hoe lang duurt het tot ik bruikbare data heb?
Hangt af van volume. Ons account had binnen 7 dagen een werkbaar rapport; kleinere accounts verzamelen er beter 30.