dataLayer and GA4 events

The events Benson pushes to window.dataLayer and GA4, their fields, when they fire, and how to use them in Google Tag Manager.

Reference
Updated 28 September 20263 min
Keep it useful

Jump to a section

Benson pushes its events to window.dataLayer, so Google Tag Manager and your own analytics can see when a coupon extension turns up, when Benson hides its pop-up, and what your discount widget does. It's on for every site by default. You don't need to add any code.

Turning it on and off#

Go to Site settings → Tracking → Integrations. There are two switches:

  • dataLayer events (on by default) pushes each event to window.dataLayer. Benson creates the array if your page doesn't have one.
  • GA4 events (off by default) sends the same events straight to Google Analytics 4 with gtag("event", ...), if gtag is on the page.

On Shopify, the dataLayer switch is also in the Benson app's settings. Neither switch needs a reinstall.

Use one route into GA4, not both. If GA4 events are on and a GTM tag also forwards the dataLayer events to GA4, every event is counted twice.

The events#

EventWhen it fires
benson_ext_detectedBenson detects a coupon extension, AI shopping agent or automation in the session.
benson_ext_blockedA blocking rule matches an extension's pop-up. benson_mode says whether Benson hid it.
benson_widget_shownYour discount widget opens on its own for the first time (not when a shopper clicks the launcher).
benson_code_appliedA code from your widget is applied to the cart.

benson_ext_detected#

window.dataLayer.push({
  event: "benson_ext_detected",
  benson_actor_class: "extension",
  benson_actor_id: "honey",
  benson_confidence: 0.96,
});
FieldValue
benson_actor_classextension, ai_agent or automation
benson_actor_idWhich one, as a lowercase slug, such as honey, capital_one_shopping or rakuten
benson_confidenceHow sure the detection is, from 0 to 1

benson_ext_blocked#

window.dataLayer.push({
  event: "benson_ext_blocked",
  benson_actor_class: "extension",
  benson_actor_id: "honey",
  benson_confidence: 0.96,
  benson_mode: "block",
});

It has the same fields as benson_ext_detected, plus:

FieldValue
benson_modeblock if Benson hid the pop-up. observe if the rule only watches, or the session is in a holdout, so the shopper still saw it.

To count pop-ups actually hidden, filter on benson_mode equals block.

benson_widget_shown#

window.dataLayer.push({
  event: "benson_widget_shown",
  benson_campaign: "cmp_8f2k1",
  benson_trigger: "exit_intent",
});
FieldValue
benson_campaignThe campaign's id
benson_triggerWhat opened it: immediate, delay, scroll, exit_intent, mobile_exit or tab_return

benson_code_applied#

window.dataLayer.push({
  event: "benson_code_applied",
  benson_campaign: "cmp_8f2k1",
  benson_method: "cart_api",
});
FieldValue
benson_campaignThe campaign's id
benson_methodHow the code went on: cart_api (the store's cart), handler (your registerApplyHandler function) or promo_input (typed into the store's discount field)

The code itself is never included.

When events fire#

  • Once per session. Each event fires once per Benson session for each extension, campaign or code. A shopper who browses ten pages with Honey installed gives you one benson_ext_detected, not ten.
  • Every session. Events fire whether or not Benson is measuring the session for your reports (see sampling in Site settings → Tracking).
  • Positive detections only. Borderline matches that Benson isn't confident about never reach the dataLayer.
  • After the page loads. Benson waits for the page to finish loading before it starts, so it never slows down your page. Anything it detected before then is pushed as soon as it starts.
  • Consent. Under strict mode, nothing is pushed while the shopper hasn't agreed.
  • No personal data. Events never carry discount codes, session ids, visitor ids or anything that identifies a shopper.

If you need every occurrence, including low-confidence matches, subscribe with Benson.on() instead. It fires each time, without the once-per-session rule.

Using the events in Google Tag Manager#

  1. Add a trigger. Create a Custom Event trigger with the event name benson_ext_detected. To catch all four with one trigger, use ^benson_ and tick Use regex matching.
  2. Add variables. Create a Data Layer Variable for each field you need, such as benson_actor_id and benson_mode.
  3. Send them on. Add a Google Analytics: GA4 Event tag on that trigger, with your variables as event parameters, for example actor_id set to {{benson_actor_id}}.
  4. Register the parameters in GA4 as custom dimensions so you can use them in reports and explorations.
  5. Publish the container.

Measure extension impact yourself shows how to use these events to compare extension sessions with everyone else.

GA4 without Tag Manager#

With GA4 events on, Benson calls gtag directly. It uses the same event names with the benson_ prefix dropped from the fields:

gtag("event", "benson_ext_detected", {
  actor_class: "extension",
  actor_id: "honey",
  confidence: 0.96,
});

Nothing is sent if gtag isn't on the page.

Checking it works#

Open your store in a browser with a coupon extension installed, such as PayPal Honey, then run this in the console:

window.dataLayer.filter((e) => String(e.event).startsWith("benson_"));

GTM's Preview mode also lists each Benson event as it arrives. Because events fire once per session, open a new private window to see them again.

Test links don't push dataLayer or GA4 events, so a test never shows up in your analytics.

Stuck? Email [email protected].

Find out what's leaking. 14 days of Own, no card.