Empty
A placeholder for screens with nothing to show yet, with an icon, a message and the next action.
Used in Pro blocks: Diff Review, API keys, Security, and 2 more
pnpm dlx shadcn@latest add https://hextaui.com/r/empty.jsonAdds the component, the HextaUI theme tokens and any HextaUI components it depends on.
Add the theme tokens to your global CSS, if you haven’t yet.
Install the dependencies.
pnpm add @base-ui/react class-variance-authority cnCopy and paste the following code into your project.
components/ui/empty.tsx Update the import paths to match your project setup.
When an empty state replaces content, its parts fade up one after another: media, title, description, then actions. Dismiss the notifications to see it. Under reduced motion it just appears. Set animated={false} for empty states that are there from the first paint.
variant="outline" draws a dashed hairline border, the usual way to mark a drop zone or an area waiting for content.
variant="muted" sits on a soft fill. The icon tile switches to a raised white surface so it still stands out.
size="sm" tightens the padding, gaps, icon tile and title for sidebars, popovers and narrow panels.
The default EmptyMedia variant only centers its content, so any avatar, badge or illustration fits.
Show who could be here, for invites and shared spaces.
Give images explicit dimensions so the layout doesn’t shift while they load.
Swap the results for an empty state when filters match nothing, and offer a way out. A visually hidden role="status" announces the count, so screen reader users hear the change without the whole list being read.
Use size="sm" with the muted variant to fill a card that has no data yet.
Put it in a single cell that spans every column with colSpan, so the header stays aligned.
A compact empty state for menus and notification panels.
<CommandEmpty /> passes the current search to a function child, so the message can quote it.
The title is a <div> so it never breaks your page outline. Render it as the heading level that fits, and label the region with it.
Unbroken names and long addresses wrap inside the container, and long button labels truncate.
Everything is centered and uses logical properties, so it reads naturally in right-to-left layouts.
<EmptyTitle />renders a<div>. Passrender={<h2 />}(or the level that fits) when the empty state is a section of the page.<EmptyMedia variant="icon" />is hidden from assistive tech because the title already says what it means. Images in the default variant stay exposed, so give them analtoralt="".- When results disappear after a search or filter, announce the change with a short
role="status"message next to the list. Don’t make the whole empty state a live region, since its buttons and links would be read every time.
Every part renders a plain element, accepts its attributes and supports the render prop to swap it.
| Prop | Type | Default |
|---|---|---|
variant | "default" | "outline" | "muted" | "default" |
sizesm tightens padding, gaps, the icon tile and the title. | "default" | "sm" | "default" |
animatedFade the parts up in sequence when the empty state mounts. Skipped under reduced motion. | boolean | true |
render | ReactElement | (props, state) => ReactElement | <div> |
| Attribute | Description |
|---|---|
data-slot="empty" | Target the root in CSS. |
data-variant | The current variant. |
data-size | The current size. |
data-animated | Present when the entrance animation is on. |
--empty-padding | Padding on every side. Set by size. |
--empty-gap | Space between the header and content. Set by size. |
| Prop | Type | Default |
|---|---|---|
render | ReactElement | (props, state) => ReactElement | <div> |
| Attribute | Description |
|---|---|
data-slot="empty-header" | Target the header in CSS. |
| Prop | Type | Default |
|---|---|---|
varianticon puts an icon in a muted tile. stack raises the tile over two fanned cards that spread when the empty state is hovered. Both hide the media from assistive tech. | "default" | "icon" | "stack" | "default" |
render | ReactElement | (props, state) => ReactElement | <div> |
| Attribute | Description |
|---|---|
data-slot="empty-icon" | Target the media in CSS. Matches shadcn. |
data-variant | The current variant. |
| Prop | Type | Default |
|---|---|---|
renderRender a heading, such as render={<h2 />}. | ReactElement | (props, state) => ReactElement | <div> |
| Attribute | Description |
|---|---|
data-slot="empty-title" | Target the title in CSS. |
| Prop | Type | Default |
|---|---|---|
renderPlain links inside are underlined. Components rendered as links keep their own style. | ReactElement | (props, state) => ReactElement | <div> |
| Attribute | Description |
|---|---|
data-slot="empty-description" | Target the description in CSS. |
| Prop | Type | Default |
|---|---|---|
render | ReactElement | (props, state) => ReactElement | <div> |
| Attribute | Description |
|---|---|
data-slot="empty-content" | Target the actions area in CSS. |
- AlertInline messages for status and feedback, with a neutral surface, a colored icon and a dismiss that collapses smoothly.
- ProgressA bar or ring that shows how far a task has come, eases between updates and slides while the total is unknown.
- SkeletonPlaceholders that wait 150ms before showing, take the exact size of the content they wrap, and fade it in without moving anything.
- SpinnerA loading indicator with Apple-style ticks or a breathing ring that can wait before showing and stay long enough not to flicker.
- ToastBrief messages that stack neatly, expand on hover, swipe away, and turn a loading state into success or error in place.
Used in Pro blocks
Blocks that build on Empty.
- Diff ReviewA review of an agent’s file edits before they land. Handles accept or reject per change, comments back to the agent and edits still streaming.
- API keysThe API keys page of an AI product. Handles a secret shown only once, revoke with undo and rotation with a grace period.
- SecurityThe Security section of an AI product’s settings. Handles sessions, two-factor with recovery codes and deletion behind a typed confirmation.
- SettingsThe settings page of an AI product. Handles a save bar that appears only when something changed, field errors and loading states.
- TeamThe team page of an AI product’s workspace settings. Handles seats running out, pending invites and ownership transfer with a typed confirmation.
Every block comes with HextaUI Pro, and Prompt Input is free.