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'
3
4<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 <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.