How to Add a Product Recommendation Quiz to Shopify Without an App

2026-09-22 · upselling

Shopify Product Recommendation Quiz Without an App: The Complete Build Guide

A product recommendation quiz does one job well: it turns a browsing shopper into a shopper with a specific product in their cart. On Shopify, the default answer is to install a quiz app, but that adds a monthly fee, another script on your storefront, and a data trail you don't control. You can build the same routing logic natively using theme sections, metafields, and Liquid. Here's how.

Why Build a Quiz Without an App (and When Not To)

The case for building it yourself:

The case against:

If you sell under roughly 50 products and your recommendations map cleanly to tags, build it yourself.

How the No-App Quiz Works: Liquid, Metafields, and a Section

The mechanics are simple once you see the pieces:

  1. A theme section holds the quiz HTML, CSS, and JavaScript. You add it to a page through the theme editor, so no code deployment is needed after the initial build.
  2. Metafields store the mapping data — for example, a custom.quiz_tags metafield on each product listing which quiz answers should surface it.
  3. Liquid renders the product cards for each result, using the metafield values to filter.
  4. JavaScript handles the question flow client-side, then either reveals a pre-rendered result block or redirects to a filtered collection URL.

The cleanest approach for most stores: render every possible result set in Liquid, hide them with CSS, and let JavaScript show the matching one. That avoids AJAX calls and keeps the quiz fast.

Step 1: Map Your Questions to Products and Tags

Before writing any code, write the quiz on paper. Bad quizzes fail here, not in the Liquid.

Pick two or three questions maximum. Each question should split your catalog meaningfully. For a coffee store selling single-origin beans, a grinder, and a subscription:

Now define tags that map to combinations. Use a consistent prefix so you don't collide with existing tags:

Answer combination Tag applied to product
Pour-over + Bright + Whole bean quiz-pourover-bright-whole
Espresso + Classic + Ground quiz-espresso-classic-ground
French press + Fruity + Whole bean quiz-frenchpress-fruity-whole
Drip + Classic + Ground quiz-drip-classic-ground

Apply these tags to products in Products → [product] → Tags. A product can carry several quiz tags — that's fine and often desirable.

A few rules that keep this maintainable:

If you'd rather not touch product tags, use a product metafield instead. Create a metafield definition under Settings → Custom data → Products with namespace custom and key quiz_tags, type List of single line text. Then enter the same values. Metafields are tidier but require editing each product's metafield panel; tags are faster to bulk-edit.

Step 2: Create the Quiz Section in Your Theme

In your Shopify admin, go to Online Store → Themes → Edit code. Under Sections, click Add a new section and name it quiz-recommender.

The section file needs three parts: schema, markup, and the result blocks.

Start with the schema so the section is configurable:

{% schema %}
{
  "name": "Quiz Recommender",
  "settings": [
    {
      "type": "text",
      "id": "heading",
      "label": "Quiz heading",
      "default": "Find your perfect match"
    },
    {
      "type": "text",
      "id": "tag_prefix",
      "label": "Quiz tag prefix",
      "default": "quiz-"
    }
  ],
  "blocks": [
    {
      "type": "result",
      "name": "Result set",
      "settings": [
        {
          "type": "text",
          "id": "result_key",
          "label": "Result key (must match a quiz tag)"
        },
        {
          "type": "text",
          "id": "result_title",
          "label": "Result headline"
        }
      ]
    }
  ],
  "presets": [{ "name": "Quiz Recommender" }]
}
{% endschema %}

The blocks array is the important piece. Each block represents one outcome — one tag combination. You'll add a block per result set in the theme editor later.

Below the schema, render the quiz container and the hidden result sets:

<div class="quiz" data-quiz>
  <h2>{{ section.settings.heading }}</h2>

  <div class="quiz__step" data-step="1">
    <p>How do you brew?</p>
    <button data-answer="pourover">Pour-over</button>
    <button data-answer="espresso">Espresso</button>
    <button data-answer="frenchpress">French press</button>
    <button data-answer="drip">Drip</button>
  </div>

  <div class="quiz__step" data-step="2" hidden>
    <p>What flavor profile do you want?</p>
    <button data-answer="bright">Bright and fruity</button>
    <button data-answer="classic">Classic and balanced</button>
  </div>

  <div class="quiz__step" data-step="3" hidden>
    <p>Whole bean or ground?</p>
    <button data-answer="whole">Whole bean</button>
    <button data-answer="ground">Ground</button>
  </div>

  <div class="quiz__results" hidden>
    {% for block in section.blocks %}
      {% assign tag = section.settings.tag_prefix | append: block.settings.result_key %}
      <div class="quiz__result" data-result="{{ block.settings.result_key }}" hidden>
        <h3>{{ block.settings.result_title }}</h3>
        <div class="quiz__products">
          {% for product in collections.all.products %}
            {% if product.tags contains tag %}
              <a href="{{ product.url }}">
                <img src="{{ product.featured_image | image_url: width: 400 }}" alt="{{ product.title | escape }}" loading="lazy">
                <span>{{ product.title }}</span>
                <span>{{ product.price | money }}</span>
              </a>
            {% endif %}
          {% endfor %}
        </div>
      </div>
    {% endfor %}
  </div>
</div>

Two things worth noting. collections.all.products caps at 50 products per page in some themes; if you have more, loop over a specific collection instead by adding a collection picker setting. And image_url is the modern filter — if your theme is older, it may use img_url instead. Check your theme's other sections to match the convention.

Step 3: Write the Liquid Logic That Routes Shoppers

The Liquid above renders every result set. JavaScript decides which one to show. Add this inside the section, after the markup:

<script>
(function () {
  const quiz = document.querySelector('[data-quiz]');
  if (!quiz) return;

  const answers = {};
  const steps = quiz.querySelectorAll('.quiz__step');
  const results = quiz.querySelector('.quiz__results');

  quiz.addEventListener('click', function (e) {
    const btn = e.target.closest('button[data-answer]');
    if (!btn) return;

    const step = btn.closest('.quiz__step');
    answers['q' + step.dataset.step] = btn.dataset.answer;

    const next = step.nextElementSibling;
    if (next && next.classList.contains('quiz__step')) {
      next.hidden = false;
      step.hidden = true;
    } else {
      step.hidden = true;
      const key = [answers.q1, answers.q2, answers.q3].join('-');
      results.hidden = false;
      const match = results.querySelector('[data-result="' + key + '"]');
      if (match) match.hidden = false;
      else results.querySelector('.quiz__result').hidden = false; // fallback
    }
  });
})();
</script>

The key is built by joining answers with hyphens, which must match your tag suffix. If a shopper's combination has no matching result block, the fallback shows the first result set rather than an empty page — never leave a dead end.

If you'd rather redirect to a filtered collection instead of showing inline results, replace the result reveal with:

window.location.href = '/collections/all/' + key;

That requires collection filters set up for those tags. Inline results are simpler and keep the shopper on the page.

Step 4: Add the Quiz to a Page With the Theme Editor

Create a page first: Online Store → Pages → Add page, title it "Find Your Coffee," and set the handle to find-your-coffee. Leave the body empty.

Then go to Online Store → Themes → Customize, navigate to the page you just created using the page selector at the top, and click Add section → Quiz Recommender.

Now add one Result set block per tag combination. The result_key must be the tag suffix without the prefix — for quiz-pourover-bright-whole, enter pourover-bright-whole. Set a headline for each, like "Bright pour-over beans for you."

Save. Visit the page on your storefront and click through every path. Check that:

Testing, Tracking, and Improving Your Quiz Results

Before you promote the quiz, verify the mapping. Open your tag list in Products → Tags and confirm every quiz- tag has at least two products assigned. An empty result set is the most common failure and the most damaging.

For tracking, fire a Shopify analytics event when a result is shown. Add this to the reveal logic:

window.ShopifyAnalytics?.lib?.track('quiz_completed', { result: key });

Then compare conversion rate for sessions that hit the quiz page against your site average in Analytics → Reports. If you use Google Analytics 4, push the same event to the data layer and mark it as a conversion.

Improvements worth testing, in order of impact:

Review the quiz monthly. Coffee catalogs rotate seasonally, so tags drift out of date fast.

Conclusion

A no-app product recommendation quiz on Shopify is a theme section, a set of tags or metafields, and about forty lines of JavaScript. It costs nothing per month, keeps shopper data in your store, and gives you total control over the recommendation logic. Build it once for a focused catalog, keep the tag mapping current, and it will outperform a generic quiz widget.

FAQ

Do I need to know how to code? You need to copy and paste Liquid and JavaScript accurately and edit a few values. If you can follow a tutorial and use the theme code editor without panicking, you can do this. If your theme is custom-built or you're not comfortable editing it, hire a Shopify developer for a one-time build.

Will this work on any Shopify theme? It works on any Online Store 2.0 theme that supports sections, which includes Dawn, Refresh, Craft, and most paid themes from recent years. Older vintage themes without section support need a different approach. Check whether your theme's Customize screen lets you add sections to pages.

What if a shopper's answers don't match any tag combination? The fallback in the code shows the first result set instead of an empty page. Better practice is to design your questions so every combination maps to a tag — with two questions of four and three options, that's twelve combinations, which is manageable to tag manually.