| Field | Value |
|---|
| ID | FRD-046 |
| Owner | David Holmes |
| Status | Draft |
| Priority | P1 — Recipes |
| Size | M (Recipe) |
| Target Release | v2.0.0 |
| Last Updated | 2026-05-26 |
| Related | ADR-027 (Default Tech Stack) |
Document Summary
Create an MDX recipe in Storybook that teaches developers how to compose a first-run onboarding experience using design system components. The recipe covers an onboarding checklist, spotlight/tooltip-based feature discovery, first-run call-to-action banners, activation tracking, a sample state machine for step progression, and analytics hook integration points. It provides copy-pasteable code for a standard SaaS first-run experience.
Introduction
Overview
First-run onboarding is the critical path between signup and activation. A well-composed onboarding flow guides new users through setup steps, highlights key features, and tracks progress toward activation milestones. Despite its importance, onboarding is often built ad-hoc with inconsistent patterns — inline tooltips that cannot be dismissed, checklists without persistence, and no analytics integration. This recipe provides the canonical composition pattern using design system components.
Goals
- Provide a single MDX recipe showing the complete onboarding flow composition.
- Show a persistent onboarding checklist (sidebar or card) with step completion tracking.
- Show spotlight/tooltip overlays for feature discovery during first use.
- Show first-run CTA banners that appear once and can be dismissed.
- Provide a sample state machine (using
useReducer or similar) for managing onboarding step progression.
- Document analytics hook integration points for activation tracking.
- Cover dismiss/skip flows so users are never trapped in onboarding.
Non-Goals
- Building a guided tour library — the recipe uses existing Tooltip/Popover components for spotlights.
- Product-specific onboarding content — the recipe shows the framework, not the copy.
- A/B testing infrastructure for onboarding variants.
- Email drip campaign integration.
- Complex multi-role onboarding paths.
Scope
In Scope
| Item | Description |
|---|
| MDX recipe page | src/docs/recipes/onboarding-flow.mdx with Storybook sidebar entry |
| Onboarding checklist | Checklist component showing steps with completion state, progress indicator |
| Spotlight overlays | Popover/Tooltip-based feature discovery pointing at UI elements |
| First-run CTA | Banner or Card that appears once for new users, dismissible |
| State machine | useReducer-based state machine for step transitions (not-started, in-progress, completed, skipped) |
| Persistence | Pattern for persisting onboarding state (localStorage for demo, API for production) |
| Analytics hooks | Integration points for tracking step completion and activation events |
| Dismiss/skip | Allow users to skip individual steps or dismiss the entire onboarding |
| Overview page update | Add Onboarding recipe to src/docs/recipes/00-overview.mdx |
Out of Scope
| Item | Reason |
|---|
| Guided tour library | Existing Popover/Tooltip components suffice for spotlights |
| Product copy and content | Recipe shows the structural pattern; content is product-specific |
| Email or notification triggers | Backend service concern |
| A/B testing framework | Experimentation infrastructure is a separate concern |
Users and Pain Points
| User | Pain Point |
|---|
| Application developer | No canonical pattern for wiring a checklist + spotlights + CTAs into a cohesive onboarding |
| Application developer | Onboarding state management is ad-hoc — boolean flags instead of a proper state machine |
| Application developer | No pattern for persisting and resuming onboarding across sessions |
| Application developer | Analytics integration points are an afterthought — hard to retrofit |
| Product manager | No visibility into onboarding completion rates because tracking was not built in |
| End user | Onboarding cannot be dismissed or skipped — creates frustration for experienced users |
Definitions
| Term | Definition |
|---|
| Onboarding checklist | A persistent UI element showing a list of setup steps with completion indicators |
| Spotlight | A tooltip or popover that points to a specific UI element to highlight a feature |
| First-run CTA | A call-to-action banner or card that appears only during the user’s first session |
| Activation | The point at which a user has completed enough onboarding steps to derive value from the product |
| State machine | A formal model of step transitions with defined states and allowed transitions |
Current State
- No onboarding recipe exists in
src/docs/recipes/.
- Components available: Checklist (
checklist.tsx), Popover (popover.tsx), Tooltip (tooltip.tsx), Card, Button, ProgressBar, ProgressStepper (progress-stepper.tsx), StepNavigation (step-navigation.tsx), Badge, Toast.
- A checklist foundation utility exists (
checklist-foundation.tsx in widgets).
- PanelWizard (
panel-wizard.tsx) exists for multi-step flows.
- The recipes overview does not currently list an onboarding recipe.
Proposed Solution
Create src/docs/recipes/onboarding-flow.mdx with the following structure:
- Introduction — What this recipe builds, when to use it, when not to use it.
- Component inventory — Table listing all components with links.
- Data model — TypeScript interfaces for
OnboardingStep, OnboardingState, and the step transition actions.
- State machine —
useReducer implementation for onboarding step management with states: not_started, in_progress, completed, skipped, dismissed.
- Onboarding checklist — Checklist component wired to the state machine, showing step progress, completion percentage.
- Spotlight overlays — Popover-based spotlights that appear when a step becomes active, pointing at the relevant UI element, with “Got it” / “Skip” actions.
- First-run CTA banner — Dismissible Card or Alert shown at the top of the main content area for new users, linking to the first uncompleted step.
- Persistence — Pattern for saving/loading onboarding state: localStorage wrapper for development, API endpoint shape for production.
- Analytics integration — Hook shape (
useOnboardingAnalytics) that fires events on step transitions: onboarding_step_started, onboarding_step_completed, onboarding_step_skipped, onboarding_dismissed, onboarding_activated.
- Dismiss and skip — Patterns for skipping individual steps and dismissing the entire onboarding, with confirmation for dismiss-all.
- Full composition — Complete code block bringing all sections together.
Requirements
| ID | Requirement | Priority |
|---|
| REQ-01 | Recipe is a single MDX file in src/docs/recipes/ | Must |
| REQ-02 | Recipe shows an onboarding checklist with step completion tracking | Must |
| REQ-03 | Recipe provides a state machine for step progression | Must |
| REQ-04 | Recipe shows spotlight/tooltip overlays for feature discovery | Must |
| REQ-05 | Recipe shows a first-run CTA banner | Must |
| REQ-06 | Recipe includes analytics hook integration points | Must |
| REQ-07 | Recipe shows dismiss/skip flows | Must |
| REQ-08 | All code blocks are copy-pasteable and self-contained | Must |
| REQ-09 | Recipe shows persistence pattern (localStorage + API shape) | Should |
| REQ-10 | Recipe references PanelWizard for multi-step wizard flows where applicable | Should |
Functional Requirements
| ID | Description | Acceptance |
|---|
| FR-01 | MDX file renders in Storybook without errors | pnpm build-storybook succeeds |
| FR-02 | All code blocks compile when extracted | Manual verification |
| FR-03 | State machine handles all transitions without invalid states | TypeScript union types enforce valid transitions |
| FR-04 | Checklist shows progress percentage and completed/total count | Code example demonstrates both |
| FR-05 | Spotlight can be dismissed and advances to the next step | Code example shows “Got it” and “Skip” handlers |
Non-Functional Requirements
| ID | Description | Target |
|---|
| NFR-01 | Recipe page load time | Under 2 seconds |
| NFR-02 | State machine code block | Under 50 lines |
| NFR-03 | Full composition code block | Under 250 lines |
| NFR-04 | No external dependencies | Recipe uses only design system components and React built-ins |
API/Interface Requirements
| Interface | Requirement |
|---|
| MDX file | Must use “ |
OnboardingStep interface | id, title, description, status, spotlightTarget (CSS selector or ref), ctaLabel, ctaAction |
OnboardingState interface | steps: OnboardingStep[], currentStepId, isActive, isDismissed, completedAt |
| State machine actions | START_STEP, COMPLETE_STEP, SKIP_STEP, DISMISS_ONBOARDING, RESET_ONBOARDING |
| Analytics hook | useOnboardingAnalytics(state: OnboardingState) — fires events on state transitions |
Accessibility Requirements
| ID | Requirement |
|---|
| A11Y-01 | Spotlight overlays must not trap focus — user must be able to Tab away |
| A11Y-02 | Checklist must use role="list" with role="listitem" for each step |
| A11Y-03 | Completed steps must be announced (e.g., via aria-label="Step 1: Complete") |
| A11Y-04 | Dismiss button must have an accessible name (“Dismiss onboarding guide”) |
| A11Y-05 | First-run CTA must use role="region" with aria-label="Getting started" |
| A11Y-06 | Spotlight must manage focus: move focus to the spotlight popover when shown, return to trigger when dismissed |
Content and Documentation Requirements
| ID | Requirement |
|---|
| DOC-01 | Update src/docs/recipes/00-overview.mdx to add Onboarding recipe |
| DOC-02 | Include a state machine diagram (text-based) showing valid transitions |
| DOC-03 | Include a “When to use” / “When not to use” section |
| DOC-04 | Document the analytics event names and payloads in a table |
Dependencies
| Dependency | Type | Risk |
|---|
| Checklist component | Internal | Must support controlled completion state |
| Popover component | Internal | Used for spotlight overlays; must support arrow pointing and controlled open state |
| ProgressBar or ProgressStepper | Internal | Used for checklist progress visualization |
| PanelWizard | Internal | Referenced for multi-step wizard flows as an alternative to spotlights |
checklist-foundation.tsx | Internal | May provide reusable checklist logic |
Risks and Tradeoffs
| Risk | Impact | Mitigation |
|---|
| Spotlight positioning depends on target element layout | May not work for all UI structures | Show the pattern using CSS selector targeting; note that complex layouts may need ref-based positioning |
| State machine adds complexity | Developers may resist adopting it | Show how boolean flags lead to impossible states; the state machine prevents bugs |
| Analytics hook is framework-agnostic but real implementations vary | Recipe may not match the team’s analytics stack | Show the hook interface; list common adapters (Segment, PostHog, Amplitude) as notes |
| Onboarding patterns are highly product-specific | Recipe may be too generic | Focus on the structural composition; include a “Customization points” section |
Open Questions
| # | Question | Status |
|---|
| 1 | Should the state machine use useReducer or recommend a library like XState? | Open — leaning useReducer for simplicity |
| 2 | Should spotlights use Popover or a dedicated Spotlight component? | Open — leaning Popover with styling |
| 3 | Should the recipe include a “resume onboarding” banner for returning users who did not complete? | Open |
| 4 | Should the checklist be a sidebar widget or an inline card? | Open — show both patterns |
Acceptance Criteria
LLM Handoff Instructions
When an LLM agent picks up this FRD:
- Read
src/docs/recipes/00-overview.mdx for recipe conventions.
- Read component source for: Checklist (
checklist.tsx), Popover (popover.tsx), Tooltip (tooltip.tsx), ProgressBar, ProgressStepper, StepNavigation, PanelWizard, Card, Button, Toast, Badge.
- Read
checklist-foundation.tsx in widgets to understand any reusable checklist logic.
- Create
src/docs/recipes/onboarding-flow.mdx with the section structure from the Proposed Solution.
- Sample onboarding steps: “Complete your profile” (name, avatar), “Create your first project”, “Invite a team member”, “Connect an integration”, “Explore the dashboard”.
- State machine: define
OnboardingStep and OnboardingState types, onboardingReducer with 5 actions, and a useOnboarding hook that wraps the reducer with persistence.
- Analytics hook:
useOnboardingAnalytics that accepts the state and fires events via a callback pattern (not tied to any specific analytics vendor).
- All code blocks must use public package import paths.
- After creating, run
pnpm build-storybook to verify.
- Update
src/docs/recipes/00-overview.mdx.
Decision Log
| Date | Decision | Rationale |
|---|
| 2026-05-26 | Use useReducer for state machine rather than XState | Lower barrier to adoption; no additional dependency; sufficient for the onboarding use case |
| 2026-05-26 | Use Popover for spotlights rather than a custom Spotlight component | Popover already supports positioning, arrows, and controlled state; avoids creating a new component |
| 2026-05-26 | Include analytics hooks as integration points, not a specific vendor | Teams use different analytics stacks; the recipe should be vendor-agnostic |
Document History
| Date | Version | Author | Changes |
|---|
| 2026-05-26 | 0.1 | David Holmes | Initial draft |