01 — Foundation

Downloads should create confidence

Good download UX reduces uncertainty. Bad download UX makes users click again in panic.

Downloads should feel reliable and predictable. Users need to know whether a download started, whether a file is still being prepared, what will land on their device, and what to do when something fails.

02 — States

What users need to see

Every phase of a download deserves explicit feedback.

  • preparation — “Generating report…” when the server builds the file
  • in progress — progress or indeterminate status for long waits
  • complete — confirm success; filename and location if helpful
  • failure — specific error with retry — see Retry Patterns

03 — Files

Naming and duplicate clicks

Mystery filenames and silent delays breed suspicion.

  • meaningful filenames — invoices-march-2026.csv, not export(3).bin
  • disable or debounce the download trigger while generation runs — see Async Actions
  • avoid starting duplicate exports without warning when one is already running
<button type="button" aria-describedby="export-status">
    Download report
</button>
<p id="export-status" role="status">Preparing your file…</p>

04 — Accessibility

Accessible download feedback

Status must reach keyboard and screen reader users.

  • role="status" or aria-live="polite" for preparation and completion
  • keyboard-accessible download controls — real links or buttons, not div click targets
  • do not rely on the browser download UI alone for server-generated files

05 — Review

Before you approve

A short checklist for download states in code review.

  • start, progress, success, and failure are all communicated
  • filenames are clear; duplicate clicks are handled
  • status is visible and announced appropriately