# Quiz

> Deterministic quizzes, product finders, assessments, branching journeys, and Shopify recommendations.

Canonical URL: https://60c719c60a9e:3005/islands/engagement/quiz

`Quiz` is the general-purpose island for product finders, shade and size
matching, assessments, gift finders, calculators, guided selling, and
content-profile quizzes.

Questions, answer keys, branching, scoring, product mappings, results, and
actions are authored in one versioned props definition. Forms are not used to
configure quiz logic.

## Core behavior

- Validates and normalizes every answer.
- Supports fixed and conditional question paths.
- Combines weighted scoring, declarative rules, point profiles, and variant
  matrices.
- Resolves current products, prices, variants, and availability from Shopify.
- Supports optional saved responses and resume for the matching page version.
- Keeps saving separate from analytics consent.
- Sends multi-product recommendations through the renderer-managed Cart V2
  command.
- Keeps multiple Quiz instances isolated on the same page.

## Question types

`single_select`, `multi_select`, `boolean`, `scale`, `number_range`, `number`,
`select`, `text`, `textarea`, `email`, `phone`, and `date`.

Email and phone questions may be saved under an explicitly approved capture
policy. A question alone does not enable collection. Saved contact information
does not subscribe a shopper to marketing or automatically email their result.

## Optional response saving

Build the quiz first, then configure capture for its exact stored page version.
The shopper can complete the quiz without saving. When saving is enabled and
chosen, the UI distinguishes pending, confirmed and failed saves and offers a
retry. Earlier answers replaced by an edit no longer determine the result.

Use the [Quiz capture workflow](/tools/forms#quiz-capture-workflow) to inspect,
prepare and activate the approved policy. Responses appear in
<AppLink to="forms">Forms</AppLink>, including unfinished attempts and completed
results. Authorized users can inspect replaced answers and export the answers
displayed to them. Agent reads expose only permitted categorical answers.

Saving, analytics and marketing are separate choices. The legacy
`analytics.answerAllowlist` prop does not enable answer-value tracking.
Quiz events contain identifiers, not raw answers.

Ordinary `preview=1` mode is for design and logic review. Production saving,
events and real cart behavior must be verified on the published page after
approval. Creating a draft or preparing a policy does not activate collection.

## Embed example

Always read the current `vibe://schema/island/Quiz` resource before authoring.

```html
<lx-island name="Quiz" hydrate="visible">
  <script type="application/json">
    {
      "schemaVersion": 1,
      "quizKey": "product_finder",
      "content": {
        "title": "Find your everyday companion",
        "description": "Choose what matters most to you.",
        "startLabel": "Find my product",
        "nextLabel": "Continue",
        "restartLabel": "Retake quiz"
      },
      "questions": [
        {
          "id": "priority",
          "type": "single_select",
          "title": "Where will you use it most?",
          "required": true,
          "options": [
            {
              "id": "everyday",
              "label": "Every day",
              "effects": [
                {
                  "target": "result",
                  "key": "daily",
                  "weight": 2
                }
              ]
            },
            {
              "id": "travel",
              "label": "On the move",
              "effects": [
                {
                  "target": "result",
                  "key": "travel",
                  "weight": 2
                }
              ]
            }
          ]
        }
      ],
      "catalog": [
        {
          "key": "full_size",
          "productId": "gid://shopify/Product/101"
        },
        {
          "key": "travel_size",
          "productId": "gid://shopify/Product/102"
        }
      ],
      "results": [
        {
          "key": "daily",
          "title": "Your everyday pick",
          "products": [
            {
              "productKey": "full_size",
              "quantity": 1,
              "reason": "Chosen for everyday use"
            }
          ],
          "actions": [
            {
              "type": "add_items",
              "label": "Add my pick",
              "openCart": true
            }
          ]
        },
        {
          "key": "travel",
          "title": "Your travel pick",
          "products": [
            {
              "productKey": "travel_size",
              "quantity": 1,
              "reason": "Chosen for use on the move"
            }
          ],
          "actions": [
            {
              "type": "add_items",
              "label": "Add my pick",
              "openCart": true
            }
          ]
        }
      ],
      "fallbackResultKey": "daily",
      "behavior": {
        "persistence": "session"
      }
    }
  </script>
</lx-island>
```

The Product GIDs above are illustrative. Replace them with real Product GIDs from `lexsis_catalog`. Do not author product prices,
availability, or resolved product objects.

## Logic

Options and `logic.dynamicScoring.entries` may add positive or negative
weights to products, variants, results, or named profiles.

`logic.rules` supports nested `all`, `any`, and `not` conditions. Rules may
include or exclude candidates, add score, set traits, force a result, select a
variant option, or add result reasons and badges.

`logic.branches` may choose another question or terminate at a result. If no
branch matches, the next authored question is used.

`logic.variantMatrices` maps answer combinations or answer axes to exact
Shopify variants. Missing and unavailable variants remain blocked; Quiz never
guesses a nearby size, shade, or flavor.

## Result actions

Supported result actions are `add_items`, `view_product`, `navigate`, and
`restart`.

`reward` and `offer` are reserved and rejected until a managed reward service
is available.

## Custom design

Quiz has no hardcoded design presets. Build each design with surrounding
section HTML, the active page theme, Quiz props, and section-scoped CSS.

The default host-only renderers are `QuizExperience`, `QuizInput`, and
`QuizResult`. They cannot be placed directly in page source.

Use `appearance.motion` with scoped state styles for transitions. Keep controls
usable during transitions, preserve heading focus, and disable nonessential
animation under `prefers-reduced-motion: reduce`. When a question container is
reused, make sure its next-question transition actually runs; an entrance
animation on the container alone may only run once. Saving and error states
must remain readable.

Common styling hooks include:

`root`, `intro`, `eyebrow`, `title`, `description`, `start-button`,
`resume-button`, `progress`, `progress-label`, `progress-track`,
`progress-fill`, `question`, `question-title`, `question-description`,
`options`, `option`, `option-media`, `option-label`, `option-description`,
`input`, `scale`, `validation-error`, `navigation`, `back-button`,
`next-button`, `review`, `evaluating`, `result`, `result-image`,
`result-title`, `result-description`, `result-badges`, `result-products`,
`result-product`, `result-price`, `result-reason`, `variant-selector`,
`result-actions`, `add-button`, `restart-button`, `loading`, `success`, and
`error`. Optional saving controls expose `data-part="capture"`. Within that
container, use the native fieldsets, labels, inputs, and status/alert roles;
there are no separate contact, choice, or error `data-part` hooks.

```css
[data-section-id='routine-quiz'] [data-part='option'] {
  border-radius: 0;
  min-height: 5rem;
}

[data-section-id='routine-quiz'] [data-part='option'][data-selected='true'] {
  box-shadow: 6px 6px 0 var(--lx-text-color);
  transform: translate(-3px, -3px);
}
```

If a design needs a fundamentally different reusable interaction surface,
engineering may register a host island with `quiz:experience`, `quiz:input`,
or `quiz:result`. Agents must use an existing registered host and cannot
invent one in page source.

## Limits

| Resource | Limit |
|---|---:|
| Questions | 30 |
| Options per question | 20 |
| Total options | 250 |
| Catalog products | 100 |
| Results | 50 |
| Products per result | 8 |
| Branch rules | 200 |
| Logic rules | 300 |
| Variant combinations | 1,000 |

## Related capabilities

- [Forms and quiz capture](/tools/forms) — Policy setup, saved responses and retention.
- [Analytics](/tools/analytics#quiz-events-and-saved-responses) — Consented quiz events and reporting boundaries.
- [Modal](/islands/engagement/modal) — Present a Quiz inside an approved modal
  composition.
- [Cart V2](/islands/cart) — Controls the effective cart drawer and commerce
  modules.
- [BundleConfigurator](/islands/commerce/bundle-configurator) — Use when the
  shopper manually fills fixed bundle slots rather than receiving a quiz
  result.
