Empty State

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'
3
4<EmptyState icon={<Bell size={16} strokeWidth={1.5} />} heading="No notifications" />

Usage

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 <EmptyState
3 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 <EmptyState
11 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<EmptyState
2 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 more
9 </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:

SlotElement
empty-stateThe root element
empty-state-icon-containerWrapper around the icon
empty-state-iconThe icon element
empty-state-contentWrapper around the heading and subheading
empty-state-headingThe heading text (when heading is set)
empty-state-subheadingThe subheading text (when subHeading is set)
empty-state-actionsWrapper around the action buttons (empty2 variant only)

Accessibility

  • The heading and subheading render as styled Text spans, 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.