Skip to content

Design system

Documentation

DesignPatterns / Empty & Error States

Patterns / Empty & Error States

Beta

Empty and error states

Empty, no-results, loading, and error states should explain what happened and point to the next useful action.

On this page

Preview

Empty and error states pattern

Give every non-happy path a clear explanation, a next action, and a status that does not rely on color alone.

No projects yet

Create the first project to give your team a place to start.

Tabs showing empty, no-results, loading, and error state compositions

State model

Empty and error state guidance
StateMeaningNext action
emptyThe feature has no records yet.Create the first record.
no-resultsRecords exist, but the current query or filters match none.Clear or change the search/filter.
loadingThe result is being requested or refreshed.Keep context and prevent duplicate reloads.
errorThe request failed and the current result is not trustworthy.Explain the failure and offer Retry.

Copy

Write from the person’s point of view. Name the object, explain the condition in plain language, and use an action that says what will happen next. Avoid vague “Something went wrong” copy and avoid apologies that do not help recovery.

empty-error-states-example.tsx
"use client";

import { Button } from "@phuctech/ui/components/button";
import { Card, CardContent, CardTitle } from "@phuctech/ui/components/card";

export function EmptyState() {
  return (
    <Card>
      <CardContent className="grid justify-items-center gap-3 p-8 text-center">
        <CardTitle>No projects yet</CardTitle>
        <p className="text-sm text-muted-foreground">Create the first project to get started.</p>
        <Button type="button">Create project</Button>
      </CardContent>
    </Card>
  );
}
  • Empty: “No projects yet” plus “Create project.”
  • No results: repeat the query or filter context and offer “Clear search.”
  • Error: say what could not load, preserve safe context, and offer “Try again.”

Accessibility

  • Keep the state heading in the document structure; do not communicate the state with an illustration or color alone.
  • Use role="status" for non-urgent loading/success updates and role="alert" only for an error that needs immediate attention.
  • Make Retry and the recovery action keyboard-focusable and keep the label specific.
  • Respect reduced motion. A spinner may be decorative, but the loading message must still be available as text.

Do and don’t

Do

Treat emptiness as an invitation to act and errors as a short path back to a trusted state.

Don’t

Show a blank container, hide the recovery action behind hover, or make the user guess whether data was deleted.

  • Button gives the recovery action a clear verb and loading state.
  • Card keeps a state message and its action together.
  • Accessibility documents the shared focus and contrast contract.