Wizards (multi-step forms) appear in checkout flows, onboarding, signup, settings. The interview tests whether you understand cross-step state management, validation strategies, and the UX details that make wizards feel polished vs frustrating.
Functional requirements
- Multiple steps, navigable in sequence
- Validation per step (cannot advance with errors)
- Step indicator (1 of 5)
- Back button to return to previous step
- Save partial progress (e.g., refresh-tolerant)
- Submit only after final step
State architecture
Single source of truth for all form data. Pass through context or a shared store.
React Hook Form has built-in support for nested forms; can register a master form across steps.
Step navigation
Two patterns:
- Linear: 1 → 2 → 3 → 4. User cannot skip.
- Branching: path depends on earlier answers. “Are you a business?” yes → business steps; no → personal steps.
Validation per step
Each step has its own validation. Strategies:
- Validate on Next button click
- Allow free movement; flag invalid steps
- Async validation (server check) before allowing Next
RHF + Zod provides good ergonomics. Each step defines its schema; combined schema validates the whole form on submit.
The “Back” question
Should clicking Back preserve user input on the current step? Almost always yes — frustrating otherwise.
If the form mutates server state at each step (rare): Back reverts the server state too, or stays at current step.
Step indicator
Common patterns:
- Numbered dots (“1 of 5”)
- Progress bar (50% complete)
- Step labels with active highlight (“Personal Info > Address > Payment”)
Show progress; reduce abandonment.
Persistence
If users abandon mid-wizard:
- Save to localStorage on each Next
- On return, restore state and offer “continue where you left off”
- Clear after successful submission or after expiration window
For high-value flows (checkout): persist to server too.
Submission
Final step submits the entire form. Patterns:
- Disable submit during in-flight request
- Show loading state
- On success: redirect or show confirmation
- On failure: surface error, jump back to relevant step if needed
Accessibility
- Each step has its own form, heading, and field labels
- aria-current on the current step in the indicator
- Focus management: when advancing, focus moves to first field of new step
- Errors announced via aria-live
Mobile considerations
- One screen per step (vertical layout)
- Sticky bottom buttons (Back / Next)
- Keyboard avoidance for inputs
- Numeric keyboard for number fields
Step transitions
Subtle slide animation between steps gives a feeling of progress. Don’t over-animate; 200–300ms is plenty.
Common antipatterns
- Lose data on back navigation
- Validation only on submit (user discovers all errors at end)
- Required fields not labeled clearly
- No progress indicator
- Confirmation modal blocking the user from changing their mind
Frequently Asked Questions
How many steps is too many?
5–7 is the sweet spot. Above 10, users abandon. Combine logically related fields per step.
Should the back button preserve the URL state?
For long flows: yes — use URL query params for the current step. Browser back works as expected.
How do I handle wizards with conditional steps?
Maintain a step graph; compute next/previous based on current state. React Hook Form’s field watchers help.