Google Tag Manager

Send Improve events to the GTM dataLayer to power Google Tag Manager & Google Ads.

Improve can mirror every analytic event onto the Google Tag Manager dataLayer. That lets your marketing team fire GTM tags and Google Ads conversions on Improve events — all from GTM, without extra engineering per event.

The mirrored improve block no longer carries the test or variant — only an anonymous visitorId. Variant attribution now happens server-side inside Improve (by joining events against the visitor's exposures), so you compare variants in the test Monitor, not by splitting GTM/Google Ads conversions on a dataLayer variable.

This is provided by the Improve SDK and is on by default. It requires an SDK version with dataLayer support — see opting out to disable it.

How it works

Whenever the SDK records an event (a page view, a click, a conversion…), it also pushes an entry like this onto window.dataLayer:

window.dataLayer.push({
	event: 'purchase',
	improve: {
		visitorId: 'visi_…', // anonymous visitor id
	},
	// value / currency and any params you pass to postAnalytic ride along too:
	value: 72.05,
	currency: 'USD',
	ecommerce: { transaction_id: 'T_1', items: [/* … */] },
	_improve: true, // marks the entry as coming from Improve
})

Because the improve block rides along on every event, any GTM tag you trigger on an Improve event can report it to Google Ads, GA4, or anywhere else. The value, currency and any params you pass to postAnalytic are spread onto the entry, so a single GTM setup can power GA4 ecommerce tracking. The test and variant are not on the entry — attribution to a variant is done inside Improve from the visitor's exposures, so use the test Monitor to compare variants.

When you pass a GA4 ecommerce object in params, the SDK pushes { ecommerce: null } first to clear any previous ecommerce object — the GTM/GA4 recommended reset that stops stale items/coupon values bleeding between events.

Before you start

  • A Google Tag Manager container installed on your site. If you host on our platform you can set NEXT_PUBLIC_GTM_ID and we'll load the container for you; otherwise add the standard GTM snippet.
  • The Improve SDK running on the same pages (this is what fills the dataLayer).

Setting up

  1. Confirm events are flowing. In GTM, open Preview and trigger an action on your site. You should see your Improve event (e.g. purchase) appear in the dataLayer with an improve object.

  2. (optional) Create Data Layer Variables for the values you pass. In GTM, go to Variables → New → Data Layer Variable for fields like value, currency, or an ecommerce object so your tags can read them. (improve.visitorId is available too; the test and variant are not on the event.)

  3. Create a trigger for your event. Triggers → New → Custom Event and set the event name to your Improve event (for example purchase). This fires whenever that event hits the dataLayer.

  4. Fire your tag. Attach the trigger to your tag — for example a Google Ads Conversion tag — and pass through the value/currency variables you need.

  5. (Google Ads) create the conversion action in Google Ads and connect it to the tag. To compare performance across variants, use the Improve test Monitor — variant attribution lives there, not in Google Ads.

Turning it off

The dataLayer push is enabled by default. To disable it, pass dataLayer: false when you set up the SDK:

const improve = new ImproveClientSDK({
	organizationId: '…',
	environment: 'production',
	dataLayer: false, // do not push events to window.dataLayer
})

The React and Next.js SDKs accept the same option in their setup args.

Good to know

  • No loops. Improve tags its own entries with _improve: true, so any importer (including Improve's own) knows to skip them.
  • GTM's own events are untouched. Improve only adds its own entries; internal gtm.* events are left alone.
  • Works without GTM, too. If GTM isn't on the page, window.dataLayer is just a harmless array — nothing breaks, the entries simply wait for a consumer.

On this page