Redirect after a quiz finishes
Goal: send the shopper to a page of your choice as soon as they finish a quiz, for example a collection that matches their answers.
Uses: Storefront JS API. Nothing to install: the API is part of the quiz embed already on the page. Events fire on the Plus and Enterprise plans.
Redirect on the finish event
Section titled “Redirect on the finish event”quiz.finished carries everything the quiz collected: the answers, the points per dimension, the products shown and the discount codes. Each answer names the question (component_key), the value as stored (value), the option ids picked for a choice (option_ids) and the labels the shopper saw (values). Put only choice answers in the URL: a text, email or phone answer is the shopper’s own words and must never land in an address that gets logged.
<script> window.octaneai = window.octaneai || []; window.octaneai.push(function (octaneai) { octaneai.on('quiz.finished', function (event) { var result = event.data.object; var params = new URLSearchParams();
result.answers.forEach(function (answer) { if (!answer.option_ids.length) return; // choice answers only, never free text params.append(answer.component_key, answer.option_ids.join(',')); }); if (result.terminal_page) params.append('result', result.terminal_page);
window.location.href = '/collections/recommended?' + params.toString(); }); });</script>quiz.finished fires once, after the result page is shown, so the shopper lands on your page rather than staying on the quiz’s own result page.
Every snippet below runs inside the same window.octaneai.push(function (octaneai) { ... }) callback: before the quiz script loads, window.octaneai is a plain array and octaneai.on does not exist yet.
Pick the page from one answer
Section titled “Pick the page from one answer”Read the answer to a specific question by its component key (the key the question has in the editor; a person’s latest_results[].answers[] on the REST API lists the same keys):
window.octaneai = window.octaneai || [];window.octaneai.push(function (octaneai) { octaneai.on('quiz.finished', function (event) { var skinType = event.data.object.answers.find(function (answer) { return answer.component_key === 'image_choice-48su5'; });
if (skinType && skinType.option_ids.indexOf('dry') !== -1) { window.location.href = '/collections/dry-skin'; } });});Pick the page from the winning dimension
Section titled “Pick the page from the winning dimension”For a points quiz, points maps each dimension id to its total:
window.octaneai = window.octaneai || [];window.octaneai.push(function (octaneai) { octaneai.on('quiz.finished', function (event) { var points = event.data.object.points; var winner = Object.keys(points).sort(function (a, b) { return points[b] - points[a]; })[0];
if (winner) window.location.href = '/collections/' + winner; });});Read the answers before the quiz finishes
Section titled “Read the answers before the quiz finishes”getState() returns what the quiz has so far: answers maps component keys to their values (saved or still on the page), page_key is the current page, and points and discount_codes are the running totals and the codes issued so far.
window.octaneai = window.octaneai || [];window.octaneai.push(function (octaneai) { octaneai.ready(function (api) { api.on('page.viewed', function () { var state = api.getState(); console.log('On page', state.page_key, 'with answers', state.answers); }); });});Every answer shows up in question.answered as it is saved, so you can also react question by question:
window.octaneai = window.octaneai || [];window.octaneai.push(function (octaneai) { octaneai.on('question.answered', function (event) { var answer = event.data.object; console.log(answer.component_key, answer.value, answer.option_ids, answer.values); });});Things to know
Section titled “Things to know”- Set
localStorage['octaneai:debug'] = '1'in the console to see every event logged as it fires. - A listener that throws is logged as
[OctaneAI] listener for quiz.finished threwand never breaks the quiz. - On a plan without the API,
window.octaneaiexists andon()registers, but no event fires and the console says so once.
