Hey folks, Rahul here ๐
Checkout flows, onboarding wizards, insurance applications โ multi-step forms are everywhere. And most implementations are fragile: lose state on refresh, validate at the wrong time, and break when the user hits the back button.
I've seen a checkout form that lost a user's credit card info on browser back-button. That's a conversion-killing bug. Let's design one that never loses data.
R โ Requirements
Functional Requirements
- Navigate between steps (next, previous, jump to step)
- Step validation before progression
- Conditional steps (skip steps based on previous answers)
- Progress indicator showing current position
- Save draft / resume later
- Review step before final submission
- File uploads within steps
Non-Functional Requirements
- Persistence: Survive page refresh, tab close, browser back
- Validation: Per-step + cross-step + async (email uniqueness check)
- Performance: Lazy-load heavy steps (file upload, rich text)
- Accessibility: Focus management on step transitions + progress announcements
- Analytics: Track drop-off per step for funnel optimization
A โ Architecture
State Machine Approach
The biggest mistake candidates make: modeling the wizard as a simple currentStep index. This breaks when you add conditional steps, validation gates, and async submission. Use a state machine:
Step Graph (Not Linear Array)
D โ Data Model
Form State
Validation Architecture
I โ Interface Definition
Wizard Hook API
Step Component Contract
O โ Optimizations
1. Focus Management on Step Transitions
2. Progress Indicator with Clickable Steps
3. Debounced Auto-Save to Server
4. Analytics: Step Drop-Off Tracking
5. Browser Back Button Integration
Production Gotchas Rahul Has Debugged ๐ฅ
- Validation Timing: Validate on blur (not on change) for text fields โ showing errors while the user is still typing is hostile UX. Validate on change only for selects and checkboxes.
- Browser Autofill: Chrome's autofill fires synthetic change events that bypass React's onChange. Listen for
inputevents as a backup, and addautoCompleteattributes to help the browser fill correctly across steps. - File Upload Persistence:
Fileobjects can't be serialized to JSON/sessionStorage. Store file metadata (name, size, type) and re-upload on resume, or use presigned URLs and store the uploaded URL instead. - Conditional Step Loops: If step B's visibility depends on step A's data, and the user goes back to step A and changes their answer, step B's data is now stale. Clear dependent steps' data when their visibility condition changes.
- Double Submission: Disable the submit button is not enough โ users can press Enter. Set a submitting flag and reject duplicate calls at the API level with an idempotency key.
Next: #13: Design a Video Player โ adaptive bitrate streaming, custom controls, buffering strategies, and PiP mode. ๐ฌ