Skip to content

Empty

Stable

Explains why there's nothing to show and what to do next — for first use, no results, cleared work and restricted access.

No projects yet

Anatomy

No projects yet
  1. 1ContainerA centered stack that stands in for missing content. The outline variant adds a dashed border inside pages.
  2. 2ActionsOne clear next step — usually the action that creates the first item.
  3. 3MediaAn icon in a raised tile, or an illustration, that sets the context.
  4. 4DescriptionWhy it's empty and what to do about it, in a sentence.
  5. 5TitleSays what's missing, in plain words.

Installation

$ pnpm dlx shadcn@latest add https://www.prfct.dev/r/empty.json

Usage

import {
  Empty,
  EmptyContent,
  EmptyDescription,
  EmptyHeader,
  EmptyMedia,
  EmptyTitle,
} from "@/components/ui/empty"
<Empty>
  <EmptyHeader>
    <EmptyMedia variant="icon">
      <FolderPlusIcon />
    </EmptyMedia>
    <EmptyTitle>No projects yet</EmptyTitle>
    <EmptyDescription>Deploy your first app in about a minute.</EmptyDescription>
  </EmptyHeader>
  <EmptyContent>
    <Button>Create project</Button>
  </EmptyContent>
</Empty>

Examples

Outline

variant="outline" draws a dashed boundary — the convention for an area that is waiting for content, like a drop zone or an empty slot in a layout.

Upload your first dataset

No results

When a search or filter returns nothing, repeat the query, suggest why, and offer ways out that don't lose the person's work.

No results for “refund policy”

All caught up

An empty state can be good news. Say so, and don't invent a call to action when there's nothing to do.

You’re all caught up

Restricted

When content exists but the person can't see it, say whose permission they need and how to ask for it.

You don’t have access to Billing

In a card

Inside a card or a table, the empty state takes the place of the content — the surrounding title and actions stay, so the context is never lost.

Integrations
Sync deploy events with your tools.
No integrations connected

For tables, see the empty table example.

Guidelines

When to use

  • First use. A feature has no data yet. Explain the value and offer the first step.
  • No results. A search or filter matched nothing.
  • Cleared. Everything is done — an inbox at zero, a finished review queue.
  • Restricted. Content exists but the person lacks permission.

When not to use

  • For errors that stop a task — use an Alert with a recovery action.
  • While data is loading — use a Skeleton in the shape of the content. Never flash an empty state before data arrives.

Writing

  • Title — state the situation in plain words: No projects yet, No results for “refund policy”. Avoid blame and exclamation marks.
  • Description — one or two sentences on why it's empty and what happens next.
  • Actions — one primary action that fills the space. Add a secondary one only when there's a real alternative.
No invoices yet
Do.Specific title, a helpful next step, one action.
Oops! Nothing here!
Don’t.Generic, emotional copy with no explanation or next step.

Imagery

Use an icon in EmptyMedia variant="icon" — it names the object that's missing. Save illustrations for first-use states on marketing-adjacent surfaces; in dense product UI they compete with the content around them.

Accessibility

  • It's content, not an alert. An empty state is regular content — don't give it role="alert". When it appears in response to a search, announce the result count in a polite live region instead ("0 results").
  • Titles aren't headings by default. EmptyTitle renders a <div>. When the empty state is a whole page or section, put a heading of the right level inside it.
  • Icons are decorative. The title carries the meaning; icons in EmptyMedia don't need labels.
  • Focus. After clearing a filter from the empty state, move focus to the results or the search field so keyboard users aren't stranded.

API reference

Empty

A centered, padded container. Accepts all div props.

PropTypeDefault
variant

Outline adds a dashed boundary for areas waiting for content.

"default" | "outline""default"

EmptyMedia

PropTypeDefault
variant

Icon puts the icon in a raised 44px tile. Default leaves the slot unstyled for illustrations.

"default" | "icon""default"

EmptyHeader

Groups the media, title and description, and limits their width for comfortable reading.

EmptyTitle

The situation, set in heading-sm.

EmptyDescription

One or two sentences in muted-foreground. Links inside it are styled.

EmptyContent

Actions and supporting controls under the header.