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.