Skip to content

Analytics & GTM

iConfigure records configurator sessions in the Manager dashboard when tracking is enabled on a product. On the host page (script inject), the tracking store also pushes events to window.dataLayer when that array exists — Google Tag Manager listens to those pushes.

Implementation source: packages/stores/tracking.js in the v2 monorepo.

Enable tracking

  1. Open Manager → your product → Submission & tracking.
  2. Enable Enable tracking to get insights (tracking_enabled on the product).
  3. Save and publish the product.

On load, _StartProductTracking in the form store starts a session and inserts a row in the Supabase tracking table. The same data appears on Dashboard and Export data → tracking.

If the insert fails, tracking is disabled for that session (no further ic_* events).

iFrame vs inject

Embed modeHost-page GTM
iFrameConfigurator JS runs in the iframe's own window. Host-page GTM does not see dataLayer.push calls.
Script injectConfigurator runs on the host windowuse this for GTM / GA4 on your site.

The code does not check embed mode explicitly; it only checks typeof dataLayer !== 'undefined'. Inject works because configurator and GTM share the same window.

Prerequisites on the host page

  1. Tracking enabled on the product in Manager.
  2. window.dataLayer must exist before the session starts — normally created by the GTM container snippet. Minimal alternative:
html
<script>window.dataLayer = window.dataLayer || [];</script>
  1. Load GTM before inject.iife.js and injectApp(). See Script inject.

GTM itself is optional; any script that defines dataLayer is enough for the pushes to land somewhere you can read.

dataLayer events (verified)

EventWhenSupabase
ic_setupSession starts after product loadInsert
ic_updateFeature change recorded + debounce (see below)Update
ic_finishSuccessful submit (info step / quotation)Update

Each push has the shape:

javascript
{ event: 'ic_setup' | 'ic_update' | 'ic_finish', data: { /* tracking object */ } }

data object (all events)

FieldDescription
user.devicee.g. smartphone, desktop
user.browsere.g. Chrome, Mobile Safari
user.ose.g. iOS, Windows
product_idProduct UUID
company_idCompany UUID
dealer_idDealer UUID or null
finishedfalse until submit; true on ic_finish
time.loadingMs from navigation start (approx.)
time.totalMs from session start (set on update/finish)
updates[]Step, feature ID, value, timestamp, timeSpentOnFeature, totalPrice

ic_setup

Fired once in trackingSetup, immediately before the Supabase insert.

ic_update — debounce

Fired from trackingUpdate when both are true:

  1. A feature change was recorded in updates[].
  2. lastChange.time - tracking.lastSync > 3000 (3 second gap).

So it is not a fixed 3-second interval timer; rapid clicks may batch into fewer pushes.

Which interactions call trackingUpdate today:

UI pathic_update
Number inputs (FormFeatureNumberBox)Yes
Radio/checkbox via legacy SelectInput (form app)Yes
Most other display widgets (buttons, toggles, dropdowns in ui-components)Not wired yet

ic_setup and ic_finish still fire regardless. For full step-level GTM on button/toggle configurators, treat ic_finish as the conversion event until selection widgets emit updates.

ic_finish

Fired in trackingFinish when submit completes successfully (useSubmitQuote, cart flow). Adds an update with changedFeature: 'info_form' and sets finished: true.

GTM setup example

1. Container snippet (head)

Standard GTM install — creates dataLayer.

2. Custom Event trigger

SettingValue
Trigger typeCustom Event
Event nameic_finish (conversion) or ic_update (engagement)

Repeat for ic_setup if you need a session-start tag.

3. Data Layer Variables

Create Data Layer Variable types in GTM:

Variable nameData Layer Variable Name
DL - product iddata.product_id
DL - finisheddata.finished
DL - total timedata.time.total

For the last feature changed, use a Custom JavaScript variable or map from data.updates in a tag template.

4. GA4 event tag (example)

SettingValue
Tag typeGoogle Analytics: GA4 Event
Event nameiconfigure_finish
TriggerCustom Event ic_finish
Event parameter product_idGTM variable DL - product id

Debug checklist

  1. Product has tracking enabled in Manager.
  2. Page uses script inject, not iframe.
  3. GTM Preview open; dataLayer exists before configurator loads.
  4. Console after load:
javascript
window.dataLayer.filter((e) => e.event?.startsWith('ic_'))
  1. Change a number feature → expect ic_update after debounce.
  2. Complete submit → expect ic_finish with data.finished === true.

Manager analytics vs GTM

SourceUse case
Manager DashboardFunnel, conversion, step drop-off (Supabase tracking)
Export data → trackingRaw CSV
GTM / GA4Marketing tags on your domain

See Tracking & analytics for the Manager side.