Prefill one quiz from another
Goal: a shopper finishes the skin quiz on the home page; when they open the routine quiz on a collection page, the questions both quizzes share are already answered.
Uses: Storefront JS API, quiz.finished (answers[]), ready(), prefill(), navigate(). Nothing to install; no API key. prefill works on every plan; quiz.finished fires on the Plus and Enterprise plans.
Save the answers when quiz A finishes
Section titled “Save the answers when quiz A finishes”answers[] holds the latest saved answer per question: component_key names the question, value is the answer as stored (an option’s value for a choice, a string for text). Keep only the questions quiz B will reuse, by their keys in quiz A, in sessionStorage, which lives for the tab and is gone when it closes.
<script> window.octaneai = window.octaneai || []; window.octaneai.push(function (octaneai) { var CARRY = ['image_choice-48su5', 'multiple_choice-goals']; octaneai.on('quiz.finished', function (event) { var carried = {}; event.data.object.answers.forEach(function (answer) { if (CARRY.indexOf(answer.component_key) !== -1) carried[answer.component_key] = answer.value; }); try { sessionStorage.setItem('octane:carried-answers', JSON.stringify(carried)); } catch (e) {} }); });</script>Prefill quiz B when it mounts
Section titled “Prefill quiz B when it mounts”On quiz B’s page, map each carried key to the key of the matching question in quiz B and stage the values with prefill(). prefill stages the values into the page’s answers; they are validated and saved when that page is submitted, by the shopper’s Next or by navigate('next').
<script> window.octaneai = window.octaneai || []; window.octaneai.push(function (octaneai) { var MAP = { 'image_choice-48su5': 'image_choice-skin', 'multiple_choice-goals': 'multiple_choice-goals' }; octaneai.ready(function (api) { var carried = null; try { carried = JSON.parse(sessionStorage.getItem('octane:carried-answers')); } catch (e) {} if (!carried) return; var values = {}; Object.keys(MAP).forEach(function (fromKey) { if (carried[fromKey] !== undefined) values[MAP[fromKey]] = carried[fromKey]; }); api.prefill(values); try { sessionStorage.removeItem('octane:carried-answers'); } catch (e) {} }); });</script>To jump the shopper past a page whose questions are all prefilled, call api.navigate('next') after the prefill in the same callback: the navigate waits for the prefilled values to render, then submits them.
Errors to handle
Section titled “Errors to handle”- A key in
valuesthat is not an answer component of quiz B is ignored byprefill; nothing throws. Check the keys in the editor when a value does not show up. - A prefilled value the question refuses (an option value quiz B does not have, text past a length limit) is rejected when the page is submitted, as
page.rejectedwithreason: 'invalid'; the shopper sees the same message as for a typed answer. prefill()before the quiz mounted logs[OctaneAI] no quiz on this page yetand does nothing;ready()is what waits for the mount.
Things to know
Section titled “Things to know”- A choice answer’s
valueis what the question stores: a list of option values (["Oily"], one entry for a single pick), each the option’s value as set in the editor (its label when no value is set). Pass it back as it came; for the prefill to land, the option must have the same value in both quizzes. - Only the current page’s staged values are submitted by a
next; a prefilled value for a later page stays staged until that page is submitted, and shows as the selection when the shopper reaches it. getState().answersshows the staged values before they are saved.- A text, email or phone answer is the shopper’s own words; the snippet removes the storage entry once it is used, and
sessionStoragenever leaves the tab.setIdentity({ email, phone })is the way to prefill identity fields; it never sets marketing consent. - Two quizzes on the same page share
window.octaneai: pass the quiz id toprefill(values, quizId)when quiz B is not the first one mounted.
