Vercel
Best Practices
When to use
- Determinate work whose total is knowable, like file uploads, multi-step setup, build steps, or batch deletions.
- For short indeterminate waits (~1–3s), use Spinner; for inline copy like
Saving, use Loading Dots.
- For usage against a quota or ratio, use Gauge; the circle reads as health, the bar reads as progress.
Behavior
- Use
max for the real ceiling (max={files.length}), not a hardcoded 100. The component computes the percentage from value / max.
- Threshold colors via
dynamic colors should mirror the same breakpoints used elsewhere (warning at the same threshold a quota note fires).
- Use stops for genuine multi-stage work and label the stage next to the bar (
Step 2 of 4 · Building); a stop with no label is decorative noise.
Content
- Pair the bar with text naming the work and units:
Uploading 12 of 30 files, Building · 1.2 GB / 4 GB. The bar alone doesn’t say what’s progressing.
- Don’t append
successfully or complete once the bar fills; swap to a completion state (toast, success row, redirect).
- For long operations, name the work in the surrounding copy (
Building deployment…) instead of leaving a bare percentage.
Accessibility
- Component sets
role="progressbar" with aria-valuemin, aria-valuemax, and aria-valuenow; pass an accessible name through aria-label on the wrapper or a sibling <label> tied with aria-labelledby.
- Throttle
aria-valuenow updates to roughly once a second so screen readers don’t announce every increment of a fast upload.
- Stops accept their own
ariaLabel; name each one (Build complete, Tests complete) so the bar is navigable without sight.
Read the original on vercel.com ↗