Designing a flow means designing all of it — not just the moment everything works.
The screen you sketch in your head is the happy path: data loads, the upload succeeds, everyone’s online. Real users hit the other paths — a dropped connection, a file that’s too big, a session that timed out.
A reliable rule of thumb: every screen that fetches or changes data has six states — empty, loading, partial, success, error, and offline. If you don’t design one, the code still reaches it — and the user gets a blank screen or a spinner that never stops.
The upload flow as a state machine
solid green = designed · dashed = not designed yet · the dot marks where the run is
turn on what goes wrong, then run the upload
The happy path is designed. Turn on a failure — say network drop — then run, and watch where the flow falls through.
Design each state
Tap a state to design it. A designed state shows the user something real; an undesigned one is where they fall through.
Walk every screen through the same checklist, then design each state deliberately — including how the user recovers.
THE SIX STATES (for any data-driven screen)
empty nothing yet -> invite the first action
loading working on it -> progress, and a way to cancel
partial some, not all -> show what worked and what didn't
success done -> confirm it, and offer undo
error it failed -> what happened / why / what next
offline no connection -> save their work, retry later
ERROR-MESSAGE ANATOMY (three parts, always)
1. what happened "Upload failed."
2. why "report.pdf is 41 MB, over the 25 MB limit."
3. what to do next "Compress it, or choose a smaller file." [Try again]
Recovery affordances — retry, undo, and preserving the user’s input — turn a dead end into a detour. An error without a next step is just a wall.
| Reach for it when | Trade-off to remember |
|---|---|
| Any screen that loads, uploads, saves, or syncs data | Designing six states per screen is more work — prioritize by how likely and how costly each path is |
| Design critiques and whiteboard rounds — a fast completeness check | Not every state needs a bespoke screen; some can be a well-worded inline message |
| Reviewing a build before ship — “show me the error and offline states” | The states interact (offline during a partial upload); the matrix can grow |
You’re asked to design photo upload for a mobile app. The tempting answer is empty → loading → success. Instead, name all six states out loud: an empty state that invites the first photo; a loading state with progress and cancel; a partial state for a batch where two of five uploaded; a success state with an undo; an error state with the full anatomy and a retry; and an offline state that saves the photo and uploads it later. Sketching offline and error — and the recovery affordances — is exactly the signal an interviewer is listening for: you design the flow, not just the screenshot.
A user with no connection taps “upload.” Which state must you have designed for them to land somewhere real?
A genuinely helpful error message includes, at minimum…
Powering your career growth.