Empty
A placeholder for sections with no content yet. Composes EmptyHeader, EmptyMedia, EmptyTitle, EmptyDescription, and EmptyContent to cover everything from minimal icons to full onboarding prompts.
Anatomy
<Empty> is a centered flex column with a dashed border. EmptyHeader groups media, title, and description. EmptyContent sits below the header for action buttons or supplemental UI.
No items
Your collection is empty.
Empty (dashed border)EmptyHeaderEmptyMedia (variant="icon")EmptyTitle / EmptyDescription
Examples
Three common compositions — from minimal to full onboarding.
Icon only
Icon + text
No results
Try adjusting your search filters.
Full (with action)
No messages
Start a conversation to get going.
Media Variants
EmptyMedia supports two variants for different visual weights.
variant="icon"Icon variant
Muted background, size-8 container, icon auto-sized to size-4.
variant="default"Default variant
Transparent background — size the icon yourself via className.
Design Guidelines
Do
- Include a call-to-action when possible. Tell users what to do next — "Create your first project" converts better than a static message.
- Use an icon to reinforce context. Choose an icon related to the content type (Inbox for messages, FolderOpen for files).
- Keep descriptions short and actionable. One sentence max — explain why it's empty and what to do about it.
Don't
- Don't show during initial loading. Show Skeleton while data is fetching — only show Empty once the fetch confirms no results.
- Don't use generic copy. "No data" or "Nothing here" is unhelpful. Be specific about what is missing and why.
- Don't stack multiple empty states. One empty state per section — multiple signals either a data problem or a layout issue.
Developer Reference
Accessibility
- Icon children inside
EmptyMediashould usearia-hidden— the title and description already provide the accessible name. - Action buttons in
EmptyContentmust have descriptive labels (avoid "Click here" or "Go"). - Data slots:
empty,empty-header,empty-icon,empty-title,empty-description,empty-content. EmptyDescriptionsupports inline links with automatic underline styling.
Usage
import {
Empty,
EmptyHeader,
EmptyMedia,
EmptyTitle,
EmptyDescription,
EmptyContent,
} from "@/components/ui/empty"
import { Inbox, Plus } from "lucide-react"
// Minimal
<Empty>
<EmptyHeader>
<EmptyMedia variant="icon">
<Inbox aria-hidden />
</EmptyMedia>
<EmptyTitle>No messages</EmptyTitle>
<EmptyDescription>Your inbox is empty.</EmptyDescription>
</EmptyHeader>
</Empty>
// With action
<Empty>
<EmptyHeader>
<EmptyMedia variant="icon">
<Inbox aria-hidden />
</EmptyMedia>
<EmptyTitle>No projects yet</EmptyTitle>
<EmptyDescription>
Create a project to get started.
</EmptyDescription>
</EmptyHeader>
<EmptyContent>
<Button>
<Plus className="size-4" />
New project
</Button>
</EmptyContent>
</Empty>