1
ComponentsFeedback

Empty

Empty explains a genuine no-content state and can provide a clear next action.

Purpose

Empty explains a genuine no-content state and can offer a clear next action. Use Skeleton for loading and Alert for an error that still has surrounding content.

Actionable empty state

No projects yet
Create a project to start planning work with your team.
import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from "@/components/ui/empty";
import { Button } from "@/components/ui/button";

export function Example() {
  return (
    <Empty>
      <EmptyHeader>
        <EmptyMedia variant="icon" />
        <EmptyTitle>No projects</EmptyTitle>
        <EmptyDescription>Create a project to start planning.</EmptyDescription>
      </EmptyHeader>
      <EmptyContent><Button>Create project</Button></EmptyContent>
    </Empty>
  );
}

Installation

With the Siteplane registry alias configured, add the component and import the installed source from your app.

CLI

pnpm dlx shadcn@4.16.1 add @siteplane/empty

Import

import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from "@/components/ui/empty";

Need the machine-readable source metadata? View registry JSON.

Usage

Use Empty to explain what happened and offer a useful next action.

import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from "@/components/ui/empty";
import { Button } from "@/components/ui/button";

export function Example() {
  return (
    <Empty>
      <EmptyHeader>
        <EmptyMedia variant="icon" />
        <EmptyTitle>No projects</EmptyTitle>
        <EmptyDescription>Create a project to start planning.</EmptyDescription>
      </EmptyHeader>
      <EmptyContent><Button>Create project</Button></EmptyContent>
    </Empty>
  );
}

Examples

Media variants, action rows and table embedding are compositions of the same slot components.

Basic

No data
Nothing has been added yet.
<Empty>
  <EmptyHeader>
    <EmptyTitle>No data</EmptyTitle>
    <EmptyDescription>Nothing has been added yet.</EmptyDescription>
  </EmptyHeader>
</Empty>

Icon media

No results
Try a different search term.
<Empty>
  <EmptyHeader>
    <EmptyMedia variant="icon">
      <SearchXIcon />
    </EmptyMedia>
    <EmptyTitle>No results</EmptyTitle>
    <EmptyDescription>Try a different search term.</EmptyDescription>
  </EmptyHeader>
</Empty>

Avatar media

The default media variant renders its child without the icon frame.

LR
User offline
This user is currently offline.
<Empty>
  <EmptyHeader>
    <EmptyMedia>
      <Avatar className="size-10">
        <AvatarFallback>LR</AvatarFallback>
      </Avatar>
    </EmptyMedia>
    <EmptyTitle>User offline</EmptyTitle>
    <EmptyDescription>This user is currently offline.</EmptyDescription>
  </EmptyHeader>
</Empty>

Primary and secondary action

No upcoming meetings
Create a meeting to get started.
<Empty>
  <EmptyHeader>
    <EmptyMedia variant="icon">
      <RouteIcon />
    </EmptyMedia>
    <EmptyTitle>No upcoming meetings</EmptyTitle>
    <EmptyDescription>Create a meeting to get started.</EmptyDescription>
  </EmptyHeader>
  <EmptyContent>
    <div className="flex flex-wrap justify-center gap-2">
      <Button>Create meeting</Button>
      <Button variant="outline">
        <BookIcon />
        View docs
      </Button>
    </div>
  </EmptyContent>
</Empty>

Table empty row

ProjectStatusOwner
No projects
Create a project to start filling this table.
<Table>
  <TableHeader>
    <TableRow>
      <TableHead>Project</TableHead>
      <TableHead>Status</TableHead>
      <TableHead>Owner</TableHead>
    </TableRow>
  </TableHeader>
  <TableBody>
    <TableRow>
      <TableCell className="p-0" colSpan={3}>
        <Empty>
          <EmptyHeader>
            <EmptyMedia variant="icon">
              <FileQuestionIcon />
            </EmptyMedia>
            <EmptyTitle>No projects</EmptyTitle>
            <EmptyDescription>
              Create a project to start filling this table.
            </EmptyDescription>
          </EmptyHeader>
          <EmptyContent>
            <Button size="sm">
              <PlusIcon />
              Create project
            </Button>
          </EmptyContent>
        </Empty>
      </TableCell>
    </TableRow>
  </TableBody>
</Table>

API Reference

The reference lists the source-owned exports and props that are easy to miss in visual examples. Inherited Base UI props remain available unless the wrapper narrows them.

  • Compose EmptyHeader, optional EmptyMedia, EmptyTitle, EmptyDescription, and optional EmptyContent.
  • A direct anchor inside EmptyDescription receives the native inline-link underline and hover treatment.
  • Put a primary recovery or creation action in EmptyContent; omit it when there is no meaningful next step.

Motion

Component motion uses the shared Siteplane motion contract. See the global motion guide for provider setup, tokens and reduced-motion behavior.

  • Empty has no mount or exit animation.
  • Actions use their own Button or link motion; do not animate the entire state.

Accessibility

  • State plainly why no content is available.
  • Give the optional action an explicit label that describes its result.
  • Use meaningful media only as supporting context; never rely on the illustration or color alone.
  • Keep inline links semantic and keyboard focusable.

Implementation Guidance

  • Use Empty only for a real zero-data state, not loading, error, or permission denial by default.
  • Keep copy concise and action-oriented.
  • Compose existing slots instead of creating a parallel empty-state primitive.

On This Page