Analytics & GTM
iConfigure registreert configuratorsessies in het Manager-dashboard wanneer tracking is ingeschakeld voor een product. Op de hostpagina (script-injectie) pusht de tracking store ook events naar window.dataLayer wanneer die array bestaat — Google Tag Manager luistert naar die pushes.
Bron van de implementatie: packages/stores/tracking.js in de v2-monorepo.
Tracking inschakelen
- Open Manager → je product → Inzending & tracking.
- Schakel Tracking inschakelen voor inzichten in (
tracking_enabledop het product). - Sla op en publiceer het product.
Bij het laden start _StartProductTracking in de form store een sessie en voegt een rij toe in de Supabase-tabel tracking. Dezelfde data verschijnt op Dashboard en bij Data → Export (dataset Tracking).
Als de insert mislukt, wordt tracking voor die sessie uitgeschakeld (geen verdere ic_update- / ic_finish-events; ic_step en ic_form_show worden nog wel gepusht).
Tracking start niet wanneer de configurator geopend wordt met mode=debug of mode=manager in de URL.
iFrame versus inject
| Insluitmodus | GTM op de hostpagina |
|---|---|
| iFrame | Configurator-JS draait in de eigen window van de iframe. GTM op de hostpagina ziet de dataLayer.push-aanroepen niet. |
| Script-injectie | Configurator draait op de host-window — gebruik dit voor GTM / GA4 op je site. |
De code controleert de insluitmodus niet expliciet; het controleert alleen typeof window.dataLayer !== 'undefined'. Inject werkt omdat de configurator en GTM dezelfde window delen.
Vereisten op de hostpagina
- Tracking ingeschakeld voor het product in Manager.
window.dataLayermoet bestaan voordat de sessie start — normaal gesproken aangemaakt door het GTM-containersnippet. Minimaal alternatief:
<script>window.dataLayer = window.dataLayer || [];</script>- Laad GTM voor
inject.iife.jseninjectApp(). Zie Script-injectie.
GTM zelf is optioneel; elk script dat dataLayer definieert is voldoende om de pushes ergens te laten landen waar je ze kunt lezen.
dataLayer-events (geverifieerd)
| Event | Wanneer | Supabase |
|---|---|---|
ic_setup | Sessie start na laden van het product | Insert |
ic_step | Bij elke stapwisseling in de configurator | Update |
ic_form_show | Het verzendformulier (offerte) wordt zichtbaar | — |
ic_update | Featurewijziging geregistreerd + debounce (zie hieronder) | Update |
ic_finish | Geslaagde verzending (infostap / offerte) | Update |
Daarnaast wordt bij elke geslaagde verzending het legacy-event offerte_submit (v1-formaat, platte offerte-velden) gepusht — onafhankelijk van tracking_enabled. In het verzendformulier van de configurator gebeurt dat direct bij het indrukken van de verzendknop; in de winkelwagen-/showroomflow en het losse contactformulier zodra de offerte is opgeslagen. In de configurator en de winkelwagen-/showroomflow krijgt de host-pagina daarna minimaal 1 seconde later pas de quotation/finished-postMessage, zodat de redirect naar de bedankt-pagina het event niet inhaalt.
De events ic_step en ic_form_show hebben een plat formaat (geen data-wrapper) zodat ze direct in GTM te gebruiken zijn:
{ event: 'ic_step', step: <1-based nummer>, step_name: '<stapnaam>', product_id, company_id, dealer_id, total_price }
{ event: 'ic_form_show', step: <1-based nummer>, product_id, company_id, dealer_id, total_price }step is altijd het stapnummer zoals de bezoeker het ziet (stap 2 in de UI → step: 2). Het verzendformulier is geen stapwaarde: het moment waarop het formulier zichtbaar wordt, meet je met het aparte event ic_form_show. Dat wordt gepusht bij de klik op de outputknop die het formulier toont (bijv. "vraag offerte aan"), of wanneer het formulier direct getoond wordt: bij het openen van de info_form-stap als het product geen outputknoppen heeft, of wanneer alle outputknoppen om contactgegevens vragen (het knoppenscherm wordt dan overgeslagen). Het wordt bij elke keer tonen opnieuw gepusht; ontdubbel in GTM als je unieke weergaven nodig hebt.
ic_step en ic_form_show worden altijd gepusht (ook zonder tracking_enabled); de bijbehorende updates[]-registratie in Supabase gebeurt voor ic_step alleen bij een actieve trackingsessie, en voor ic_form_show nooit (alleen dataLayer). De velden product_id / company_id / dealer_id zijn alleen gevuld tijdens een actieve trackingsessie — zonder tracking_enabled zijn ze null.
Elke push heeft de vorm:
{ event: 'ic_setup' | 'ic_update' | 'ic_finish', data: { /* tracking-object */ } }data-object (alle events)
| Veld | Beschrijving |
|---|---|
user.device | bijv. smartphone, desktop |
user.browser | bijv. Chrome, Mobile Safari |
user.os | bijv. iOS, Windows |
product_id | Product-UUID |
company_id | Bedrijf-UUID |
dealer_id | Dealer-UUID of null |
email | Leeg tot verzending; het e-mailadres van de bezoeker bij ic_finish |
finished | false tot verzending; true bij ic_finish |
time.loading | Ms vanaf start van de navigatie (bij benadering) |
time.total | Ms vanaf start van de sessie (ingesteld bij update/finish) |
updates[] | Stap, feature-ID, waarde, timestamp, timeSpentOnFeature, totalPrice |
Bij ic_finish bevat het data-object daarnaast phone, first_name en last_name wanneer de bezoeker die heeft ingevuld (alleen in de dataLayer, niet opgeslagen in de Manager).
ic_setup
Eenmalig afgevuurd in trackingSetup, vlak voor de Supabase-insert.
ic_update — debounce
Afgevuurd vanuit trackingUpdate wanneer beide waar zijn:
- Er is een featurewijziging geregistreerd in
updates[]. lastChange.time - tracking.lastSync > 3000(3 seconden tussenruimte).
Het is dus geen vaste timer van 3 seconden; snelle klikken kunnen samengebundeld worden tot minder pushes.
Welke interacties roepen vandaag trackingUpdate aan:
| UI-pad | ic_update |
|---|---|
Numerieke invoer (FormFeatureNumberBox) | Ja |
Radio/checkbox via oude SelectInput (form-app) — lijst, afbeeldingsknoppen, ronde knoppen, carrousel, afbeeldingslijst, afbeeldingsslide en selectieslider | Ja |
| Andere weergavewidgets (dropdown, schakelaar, kleurkiezer, tekstvelden) | Nog niet gekoppeld |
ic_setup, ic_step en ic_finish worden hoe dan ook afgevuurd. Voor GTM op featureniveau bij dropdown-/schakelaarconfigurators gebruik je ic_step voor de voortgang en ic_finish als conversie-event totdat die widgets updates uitzenden.
ic_finish
Afgevuurd in trackingFinish wanneer de verzending succesvol voltooit (useSubmitQuote, winkelwagenflow, los contactformulier). Voegt een update toe met changedFeature: 'info_form' en zet finished: true.
Voorbeeld van GTM-instelling
1. Containersnippet (head)
Standaard GTM-installatie — maakt dataLayer aan.
2. Custom Event-trigger
| Instelling | Waarde |
|---|---|
| Triggertype | Custom Event |
| Eventnaam | ic_finish (conversie), ic_form_show (formulierweergave / funnel) of ic_update (engagement) |
Herhaal voor ic_setup als je een tag voor sessiestart nodig hebt.
3. Data Layer-variabelen
Maak Data Layer Variable-types aan in GTM:
| Variabelenaam | Data Layer Variable Name |
|---|---|
| DL - product id | data.product_id |
| DL - finished | data.finished |
| DL - total time | data.time.total |
Gebruik voor de laatst gewijzigde feature een Custom JavaScript-variabele of map vanuit data.updates in een tagtemplate.
4. GA4-event-tag (voorbeeld)
| Instelling | Waarde |
|---|---|
| Tagtype | Google Analytics: GA4 Event |
| Eventnaam | iconfigure_finish |
| Trigger | Custom Event ic_finish |
Eventparameter product_id | GTM-variabele DL - product id |
Debug-checklist
- Product heeft tracking ingeschakeld in Manager.
- Pagina gebruikt script-injectie, geen iframe.
- GTM Preview open;
dataLayerbestaat voordat de configurator laadt. - Console na het laden:
window.dataLayer.filter((e) => e.event?.startsWith('ic_'))- Wijzig een numerieke feature → verwacht
ic_updatena debounce. - Voltooi een verzending → verwacht
ic_finishmetdata.finished === true.
Manager-analytics versus GTM
| Bron | Toepassing |
|---|---|
| Manager-dashboard | Funnel, conversie, uitstroom per stap (Supabase tracking) |
| Data → Export (Tracking) | Ruwe export (CSV of JSON) |
| GTM / GA4 | Marketingtags op jouw domein |
Zie Marketingdashboard voor de Manager-kant.