Make the page react to the quiz
Goal: the page around the quiz follows it: a colour per quiz page, the header hidden on the result page, a track that starts once the shopper is in.
Uses: Storefront JS API, page.viewed, quiz.started, quiz.finished, quiz.closed. Nothing to install; no API key. Events fire on the Plus and Enterprise plans.
Mirror the quiz page on <html>
Section titled “Mirror the quiz page on <html>”page.viewed fires when a page lands (the first page at mount, every later one once the server confirmed it). Put its page_key on the root element and let CSS do the rest:
<script> window.octaneai = window.octaneai || []; window.octaneai.push(function (octaneai) { octaneai.on('page.viewed', function (event) { var page = event.data.object; var root = document.documentElement; root.setAttribute('data-quiz-page', page.page_key); root.setAttribute('data-quiz-page-index', String(page.page_index)); root.classList.toggle('quiz-done', page.terminal_page !== null); }); octaneai.on('quiz.closed', function () { document.documentElement.removeAttribute('data-quiz-page'); }); });</script><style> html[data-quiz-page] body { transition: background-color 400ms; } html[data-quiz-page="skin"] body { background-color: #f4efe6; } html[data-quiz-page="goals"] body { background-color: #e6eef4; } html.quiz-done body { background-color: #111; color: #fff; } html.quiz-done .site-header { display: none; }</style>page_key is the key the page has in the editor. terminal_page is the page key when this landing completed the quiz, otherwise null; quiz.finished fires right after that landing, so either works for “the shopper is on the result”.
Start music on the first answer
Section titled “Start music on the first answer”Browsers refuse audio.play() without a user gesture, and the first page.viewed fires at mount before the shopper touched anything. quiz.started fires when the first answer is saved, which is always after a click, so start there:
window.octaneai = window.octaneai || [];window.octaneai.push(function (octaneai) { var track = document.getElementById('quiz-music'); octaneai.on('quiz.started', function () { if (track) track.play().catch(function () {}); }); octaneai.on('quiz.finished', function () { if (track) track.pause(); });});Errors to handle
Section titled “Errors to handle”- A listener that throws is logged as
[OctaneAI] listener for page.viewed threwand never breaks the quiz; there is nothing to catch on your side. play()still rejects when the browser’s autoplay policy blocks it (a shopper who navigated here without interacting with the site); the.catchabove keeps that silent.
Things to know
Section titled “Things to know”- A page-link button’s jump is client-side and is not reported; the next confirmed page names the last confirmed page as
previous_page_key. quiz.closedfires only for a fullscreen quiz (its X, oroctaneai.close()); an inline quiz has no close.- Two quizzes on one page both fire
page.viewed; pass{ quizId }toon()to follow one of them. - Restyling the quiz itself this way does not work: the quiz renders inside a shadow root and its theme variables are set inside it, so host CSS does not reach in.
- Set
localStorage['octaneai:debug'] = '1'in the console to see every event as it fires.
