Every multi-step flow starts innocently — a checkout, an onboarding wizard, a booking form — and ends as a nest of boolean flags nobody dares to touch. The way out is to model the flow explicitly instead of inferring it from scattered state.
Think in states, not flags
List the steps a user can actually be in, and the events that move them between steps. A tiny state machine — even a hand-rolled one with a step value and a transition function — makes impossible states unrepresentable and renders a honest progress indicator trivial.
Make steps shareable and survivable
Put the current step in the URL so refreshes, back buttons and shared links land in the right place. Persist draft answers locally so a dropped connection doesn't vaporize twenty minutes of effort. These two details separate flows users tolerate from flows they trust.
- One source of truth for the current step; derive everything else.
- Validate per step on continue, and re-validate everything on submit.
- Save drafts automatically — never punish a refresh.
Complex flows stay manageable when the machine is boring and the UI is kind. Boring machines are debuggable; kind UIs convert.
Mateo Alvarado
Web developer & UI/UX designer, Semicolon Studio