EmptyState
A placeholder for views with nothing to show yet — pairs an icon and message with optional actions to help users take the next step.
Overview
EmptyState fills a view that has no content yet — an empty inbox, zero search results, a feature that needs setup. It pairs a required icon with an optional heading, subHeading, and up to two action slots (primaryAction, secondaryAction) so users always have a next step.
Use empty1, the default, for compact centered placeholders inside panels and lists. Use empty2 for full-page states, which left-align the content and put the actions in a side-by-side row.
Anatomy
Import and assemble the component:
1import { EmptyState } from '@raystack/apsara'2import { Bell } from 'lucide-react'34<EmptyState icon={<Bell size={16} strokeWidth={1.5} />} heading="No notifications" />
Usage
Pick the variant that suits the space, then fill in the icon, the message and up to two actions.
Variants
empty1 (the default) centers everything and stacks the actions vertically — suited to panels, tables, and lists. empty2 left-aligns the content, uses a larger icon, and places both actions in a row — suited to full-page states.
1<Flex gap={9}>2 <EmptyState3 variant="empty1"4 icon={<Bell size={16} strokeWidth={1.5} />}5 heading="No notifications yet"6 subHeading="When you have notifications, they will appear here"7 primaryAction={<Button>Enable notifications</Button>}8 secondaryAction={<Button variant="ghost">Learn more</Button>}9 />10 <EmptyState11 variant="empty2"12 icon={<Bell size={16} strokeWidth={1.5} />}13 heading="Organization"14 subHeading="An organization in Aurora is a shared workspace where teams manage projects, AOIs, and image orders. It streamlines collaboration, analysis, and decision-making across industries."15 primaryAction={<Button>Enable notifications</Button>}
Icon, headings and actions
heading states what is missing, subHeading says what to do about it. primaryAction is the way out; add secondaryAction only when there is a genuine second path, since two equal buttons make the choice harder.
1<EmptyState2 icon={<Search />}3 heading="No matching invoices"4 subHeading="Check the spelling, or clear the filters to see everything."5 primaryAction={<Button size="small">Clear filters</Button>}6 secondaryAction={7 <Button size="small" variant="outline">8 Learn more9 </Button>10 }11/>
API Reference
Renders a placeholder for empty content areas.
Prop
Type
Slots
Every rendered part carries a stable data-slot attribute for styling and testing:
| Slot | Element |
|---|---|
empty-state | The root element |
empty-state-icon-container | Wrapper around the icon |
empty-state-icon | The icon element |
empty-state-content | Wrapper around the heading and subheading |
empty-state-heading | The heading text (when heading is set) |
empty-state-subheading | The subheading text (when subHeading is set) |
empty-state-actions | Wrapper around the action buttons (empty2 variant only) |
Accessibility
- The heading and subheading render as styled
Textspans, not real heading elements, so they don't join the document outline. If the empty state is the main content of a page, consider passing a real heading (e.g.heading={<h2>…</h2>}) to keep the outline intact. - The icon is decorative by default. If it carries meaning on its own,
give it an accessible name; otherwise mark it
aria-hidden. - Actions are whatever you pass in — use real
Buttons so keyboard and screen reader users can reach them.