Build a quiz or recommendation flow
I want visitors to answer questions and get a personalized recommendation.
Author a scored flow in the dashboard, publish a public link, and render it on your site. Branching and scoring are server-side; the result bands are your recommendations.
Typical effort: 20 minutes, no engine code
The recipe — paste this to your AI
# Recipe — build a quiz, survey, or recommendation flow on your public site
Your site ships the Genesis **questions engine** as a public renderer: an operator authors a
flow (questions, branching, scoring) in the dashboard at **Questions**, publishes a public
link, and any page on this site can render it. Branching and scoring are **server-side** — the
rules never reach the browser — and answers land in your organization as structured responses.
This is how you build a "**which package is right for me?**" recommendation quiz, an intake
survey, a lead qualifier, or a scored assessment — with **zero engine code**.
## What ships already (don't rebuild these)
| Piece | Where |
|---|---|
| Public fill page (anyone with the link) | `/form/<publicLinkKey>` |
| Public survey/embed page | `/q/<slug>`, tokened invites at `/q/invite/<token>` |
| The typed client | `flowPublicApi` in `lib/api/flow.ts` — `resolve` / `step` / `submit` |
| The player component | `components/flow/flow-player.tsx` (renders any flow) |
| The result view | `components/flow/flow-result.tsx` (score, band label, thank-you) |
| Booking hand-off inside a flow | `components/flow/flow-slot-picker.tsx` |
The scoring contract (from `lib/api/flow.ts`) is what makes recommendations work:
```ts
interface FlowSubmitResult {
totalScore: number;
normalizedScore?: number | null; // 0–1 fraction of best achievable (quiz mode)
scoreLabel?: string | null; // the operator-named band, e.g. "Growth plan fits you"
showResultPage?: boolean;
}
```
The operator defines **score bands** (`minScore` → `label`) in the dashboard — the band label
IS the recommendation. Change the bands or questions in the dashboard and the live site
updates; no redeploy.
## Step 1 — author the flow (dashboard, ~10 minutes, no code)
1. Dashboard → **Questions** → create a flow. Add your questions; reuse library questions
where offered (they carry canonical keys, so answers become durable profile facts).
2. For a recommendation quiz: give answer options **point values**, then define **result
bands** — each band's label is what the visitor will be told ("You need the Starter kit" /
"Talk to us about the Pro plan"). Enable the result page.
3. **Publish** and copy the **public link key** (the token in the `/form/<key>` URL).
## Step 2 — put it on your site (a lane page — upgrade-safe)
Option A — just link it: add the `/form/<key>` URL to `site.config.ts → marketing.nav` or any
CTA. Done.
Option B — a branded page around it (recommended for a recommendation quiz). The canonical
wiring lives in `app/form/[publicLinkKey]/page.tsx` — **copy that file into your own segment**
and brand around it. The load-bearing shape (what the framework page does for you):
```tsx
// app/(marketing)/recommend/page.tsx — YOURS (a new segment = a lane).
// Start by copying app/form/[publicLinkKey]/page.tsx, hardcode YOUR key, then
// wrap it in your hero/branding. The wiring it gives you:
// 1. flowPublicApi.resolve(key) → the flow definition to render
// 2. <FlowPlayer flow={flow}
// step={(answers) => flowPublicApi.step(key, answers)} // server-side branching
// onSubmit={(answers) => submitMutation.mutate(answers)} /> // → FlowSubmitResult
// 3. on result: render <FlowResult …> (score + band label), then YOUR
// band→CTA mapping (deep-link each scoreLabel to a service or booking page).
```
`FlowPlayer` takes a **resolved flow** plus `step`/`onSubmit` callbacks — it does not fetch by
key itself; the resolve/step/submit calls stay in your page, exactly as the framework form page
does them. Then make your page reachable and findable in `site.config.ts`:
```ts
marketing: {
nav: [ /* … */, { label: 'Find your fit', href: '/recommend' } ],
publicPaths: ['/recommend'], // reachable without login
sitemapPaths: ['/recommend'], // indexed by search engines
},
```
## Step 3 — route the result somewhere useful
On submit you get `scoreLabel`. Map bands to next steps on YOUR page — deep-link each
recommendation into the matching service, package, or booking page. The mapping lives in your
lane file, so marketing can retune bands in the dashboard without touching code.
## Rules that keep it correct
- The flow definition, branching, and scores are **operator-owned data** — never hardcode
question text or scoring in the page. The page renders whatever the dashboard publishes.
- Answers may contain personal data: the public endpoints are already rate-limited and
org-scoped server-side. Don't cache responses in the browser.
- Run `pnpm verify` before shipping, as with any new page.
Source of truth
This recipe ships inside the template as docs/prompts/build-a-quiz-or-flow.md — this page renders that exact file. The repository is always the newest version: https://github.com/srisenmay/bringthefront-template. Clone the template and you get every recipe locally, versioned with the release you are on.