Skip to content

Send quiz events to a tag manager

Goal: every quiz event but identity.captured reaches Google Tag Manager (or Segment, or any script on the page) as a data layer push, with no personal data forwarded.

Uses: Storefront JS API, the document mirror. Nothing to install; no API key. Octane AI’s own Google Analytics and Meta integrations are configured in the dashboard; this recipe is for everything else.

Every event is also dispatched on document as a CustomEvent named octaneai:<type> with the envelope in event.detail, so a listener works even when it is added before the quiz script loads, and a tag manager custom-event trigger can hear it. There is no wildcard: subscribe by name.

<script>
(function () {
var TYPES = [
'quiz.viewed', 'quiz.started', 'page.viewed', 'page.rejected', 'question.answered',
'quiz.finished', 'product.shown', 'product.clicked', 'cart.add_requested',
'cart.added', 'cart.failed', 'discount.issued', 'discount.copied', 'quiz.closed', 'error'
];
TYPES.forEach(function (type) {
document.addEventListener('octaneai:' + type, function (e) {
var o = Object.assign({}, e.detail.data.object);
delete o.identities; // quiz.finished
delete o.answers; // quiz.finished
delete o.value; // question.answered: may be free text
delete o.values;
delete o.product; // product events: keep the ids only
delete o.session_id; // links the visit to a person on the REST API
delete o.visitor_id; // quiz.viewed
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({ event: 'octane_' + type.replace('.', '_'), octane: o });
if (window.analytics) window.analytics.track('Quiz ' + type, o);
});
});
})();
</script>

identity.captured is left out on purpose: it carries the email or phone the shopper just typed. question.answered’s value and values can be free text, so they are dropped too; keep component_key and option_ids, which are safe to count on.

Every object carries quiz_id, quiz_name, version_id and version_number, so a report can be split by quiz and by published version; session_id and visitor_id are dropped above because they tie the visit to a person on the REST API. The rest per event:

EventUseful for a tag
quiz.viewedplacement (inline, fullscreen, tapcart)
page.viewedpage_key, page_index, terminal_page (the result page reached)
page.rejectedpage_key, fields[].component_key, fields[].reason (required or invalid)
question.answeredcomponent_key, option_ids
product.shown, product.clickedproduct_id, variant_id (Shopify GIDs), block_key, recommendation_source / action
discount.issued, discount.copiedcode, discount_id
errorcode, request_id

In GTM, create a Custom Event trigger per name (octane_quiz_finished) and read the fields as Data Layer variables (octane.quiz_id, octane.terminal_page).

  • Listeners registered with octaneai.on() run before the document event, and the two see the same frozen data.object.
  • Events fire on the Plus and Enterprise plans; on another plan nothing is dispatched on document (the console note about the plan appears only when something calls octaneai.on()).
  • To see what is flowing, set localStorage['octaneai:debug'] = '1' in the console.