Error
Good error design is clear, useful, and friendly. Designing concise and accurate error messages unblocks users and builds trust by meeting people where they are.
Default
This email address is already in use.
Custom label
Email Error:This email address is already in use.
No label
Email Error:This email address is already in use.
Sizes
This email is in use.
This email is in use.
This email is in use.
With an error property
The request failed. Contact Us
Best Practices
When to use
- Use the Error component as a block surface when a section or page-level resource failed to load: a panel, a dashboard card, a route boundary.
- Pick
toasts.error()for transient action failures (Couldn’t save settings. Try again.) and theerrorprop on Input for field-level validation. Don’t replace either with this block. - Always pair platform or system errors with a stable identifier (request ID
x-vercel-id, deployment IDdpl_…, run ID, trace ID). Validation and permission denials are user-state, not system, and don’t need an ID.
Behavior
- The recovery action must do something concrete: a
Try Againbutton when the operation is retry-safe, a named verb (Reconnect GitHub,Update Payment Method) when it isn’t. - Don’t auto-retry in the background; the user came to this surface to decide.
- For full-page route errors (
error.tsx), return focus to theTry Againbutton on appearance so a keyboard user can retry without hunting for it.
Content
- State what happened and what to do next, in that order. Cut apologetic preambles (
Unfortunately,Oops,We’re sorry). - Use
Couldn’torCan’tfor user-state errors (Couldn’t verify your passkey. Try again.); useFailed tofor system or infra errors that mirror CLI output (Build failed. Bundle exceeds 50 MB.).Unable tois banned. - Don’t fall back to
Something Went Wrongas a title; name the resource that failed (Couldn’t Load Page,Couldn’t Load Deployments). - Render the stable ID on a monospace sub-line under a collapsed
<details>so the user can copy-paste it into a support thread. - Never humor an error. Users hitting an error are frustrated; insincere copy makes it worse.
Accessibility
- When the error appears asynchronously (after a failed fetch), wrap the region in
aria-live="polite"so it’s announced. Reservearia-live="assertive"for true blocking errors that interrupt input.
Was this helpful?