GTM tracking bridge
When checkout and side-cart events don’t reach Dialog automatically (anything that’s not Shopify or Prestashop), you wire them via the window.DialogTracking bridge. This is the most common path because almost everyone already has GTM tagging their cart and checkout events.
What the bridge does
Section titled “What the bridge does”When the Dialog widget is loaded on a page, it exposes:
window.DialogTracking.track(eventName, payload)You call this from GTM tags to forward an add_to_cart or purchase event to Dialog. Anything else is ignored — only those two events are accepted.
Prerequisites
Section titled “Prerequisites”- The Dialog widget script must be loaded on the page where you call
window.DialogTracking.track(...). Most importantly, make sure the widget script tag fires on your purchase confirmation page — that’s the most common reasonwindow.DialogTrackingis undefined when your purchase tag fires. - You have edit access to your GTM container.
- The events you want to forward already live in GTM (typically via existing dataLayer pushes from your site or a GA4 / Ecommerce setup).
Supported events
Section titled “Supported events”Only these two:
add_to_cartpurchase
Payload spec
Section titled “Payload spec”Common fields
Section titled “Common fields”| Field | Type | Description |
|---|---|---|
value | number | Total event value (cart subtotal for add_to_cart, order total for purchase). |
currency | string | ISO currency code, e.g. "EUR", "USD". |
items | array (optional) | Items affected — see whitelist below. |
purchase adds
Section titled “purchase adds”| Field | Type | Description |
|---|---|---|
transaction_id | string | Unique transaction or order ID. |
Allowed item fields
Section titled “Allowed item fields”Whitelist (other fields are dropped):
item_iditem_namepricequantityitem_branditem_categoryitem_variantindexcoupondiscount
GTM implementation
Section titled “GTM implementation”Tag 1: forward purchase
Section titled “Tag 1: forward purchase”In GTM, create a Custom HTML tag named Dialog: forward purchase.
Trigger: your existing purchase trigger (typically on the order confirmation page).
<script> if (window.DialogTracking && typeof window.DialogTracking.track === 'function') { window.DialogTracking.track('purchase', { transaction_id: 'TRANSACTION_ID', value: VALUE, currency: 'CURRENCY', items: ITEMS }); }</script>Replace TRANSACTION_ID, VALUE, CURRENCY, ITEMS with your GTM variables. items is optional.
Tag 2: forward add_to_cart
Section titled “Tag 2: forward add_to_cart”<script> if (window.DialogTracking && typeof window.DialogTracking.track === 'function') { window.DialogTracking.track('add_to_cart', { value: VALUE, currency: 'CURRENCY', items: ITEMS }); }</script>The if (window.DialogTracking) guard is mandatory — see the race condition note below.
Race condition: the most common gotcha
Section titled “Race condition: the most common gotcha”window.DialogTracking is set by the Dialog widget script after it has loaded and initialised. If your GTM tag fires before the widget script has run, window.DialogTracking is undefined and the call does nothing — the event is silently dropped.
The two safe patterns:
- Keep the
if (window.DialogTracking)guard (always). At worst, an event is missed; at best, your tag never throws. - Sequence your triggers. On a confirmation page, fire your purchase tag after the widget script has loaded — e.g. trigger on
DOMContentLoadedor a custom event you push to the dataLayer once the widget says it’s ready.
Concretely: if your purchase tag fires on Page View - DOM Ready and the widget loads asynchronously, you’ll lose purchases. Switch to Window Loaded or wrap the call in a small retry loop:
<script> (function tryTrack(attempts) { if (window.DialogTracking && typeof window.DialogTracking.track === 'function') { window.DialogTracking.track('purchase', { transaction_id: 'TRANSACTION_ID', value: VALUE, currency: 'CURRENCY', items: ITEMS }); return; } if (attempts <= 0) return; setTimeout(function () { tryTrack(attempts - 1); }, 200); })(20); // up to 4 seconds of polling</script>This is the pattern we recommend on confirmation pages where you can’t afford to lose the purchase event.
What you must have on the page
Section titled “What you must have on the page”For the bridge to exist, the Dialog widget script must run on the page where you call window.DialogTracking.track(...). The exact tag depends on your install:
- GTM install → the same
<script src="https://cdn.askdialog.com/assets/dialog-instant.js?..."></script>tag you set up in Install via Google Tag Manager. Make sure its trigger fires on your confirmation page as well, not just product pages. - SDK / React / Vue install → the SDK is bundled with your frontend, so the bridge is exposed wherever your storefront code runs. Just make sure your confirmation page is rendered by the same frontend (typical SPA) — server-rendered confirmation pages outside your SPA won’t have the SDK loaded.
QA checklist
Section titled “QA checklist”- Open your site with the Dialog widget loaded.
- In the browser console, type
window.DialogTracking. It must be defined. - Trigger an add-to-cart. Confirm in the Dialog dashboard that the side-cart event fires.
- Trigger a purchase. Confirm the checkout event fires.
Troubleshooting
Section titled “Troubleshooting”| Symptom | Likely cause | Fix |
|---|---|---|
window.DialogTracking is undefined | Widget script not loaded on that page, or it hasn’t finished initialising | Verify the widget script tag is present and fires on this page; use the retry pattern above |
| Purchase tag fires on confirmation page but Dialog reports nothing | Race condition — the tag fires before the widget script finishes loading | Move the trigger to Window Loaded, or wrap the call in the retry loop above |
Wrong value or currency | GTM variables resolve too late | Move the tag to a later trigger or read from a stable dataLayer push |
Next steps
Section titled “Next steps”- Tracking overview — what’s automatic vs manual per install path.
- SDK custom tracking — the alternative when you’d rather call SDK methods directly from your frontend code.