Skip to content
Esc
navigateopen⌘Jpreview
On this page

Empty

Use the Empty component to display an empty state.

No projects yet
You haven't created any projects. Get started by creating your first one.
import { Button } from '@/components/ui/button';
import {
  Empty,
  EmptyContent,
  EmptyDescription,
  EmptyHeader,
  EmptyMedia,
  EmptyTitle,
} from '@/components/ui/empty';

export default function EmptyDemo() {
  return (
    <Empty>
      <EmptyHeader>
        <EmptyMedia variant="icon">
          <svg
            width="16"
            height="16"
            viewBox={`0 0 16 16`}
            fill="none"
            stroke="currentColor"
            strokeWidth="1.5"
            strokeLinecap="round"
            strokeLinejoin="round"
            aria-hidden
          >
            <path d={`M2 5.5 8 2l6 3.5v5L8 14l-6-3.5z M8 8v6 M2 5.5 8 8l6-2.5`} />
          </svg>
        </EmptyMedia>
        <EmptyTitle>No projects yet</EmptyTitle>
        <EmptyDescription>
          You haven't created any projects. Get started by creating your first
          one.
        </EmptyDescription>
      </EmptyHeader>
      <EmptyContent>
        <Button size="sm">Create project</Button>
      </EmptyContent>
    </Empty>
  );
}

Install

npx shadcn@latest add @madeui/empty

Usage

import {
  Empty,
  EmptyContent,
  EmptyDescription,
  EmptyHeader,
  EmptyMedia,
  EmptyTitle,
} from '@/components/ui/empty';

Composition

<Empty>
  <EmptyHeader>
    <EmptyMedia variant="icon" />
    <EmptyTitle />
    <EmptyDescription />
  </EmptyHeader>
  <EmptyContent />
</Empty>

Outline

Override style on Empty for a solid border instead of the default dashed one.

No messages
You're all caught up. New messages will show up here.
import * as stylex from '@stylexjs/stylex';

import { Button } from '@/components/ui/button';
import {
  Empty,
  EmptyContent,
  EmptyDescription,
  EmptyHeader,
  EmptyMedia,
  EmptyTitle,
} from '@/components/ui/empty';

export default function EmptyOutline() {
  return (
    <Empty style={styles.root}>
      <EmptyHeader>
        <EmptyMedia variant="icon">
          <svg
            width="16"
            height="16"
            viewBox={`0 0 16 16`}
            fill="none"
            stroke="currentColor"
            strokeWidth="1.5"
            strokeLinecap="round"
            strokeLinejoin="round"
            aria-hidden
          >
            <path d={`M2 4.5h12M2 8h12M2 11.5h7`} />
          </svg>
        </EmptyMedia>
        <EmptyTitle>No messages</EmptyTitle>
        <EmptyDescription>
          You&apos;re all caught up. New messages will show up here.
        </EmptyDescription>
      </EmptyHeader>
      <EmptyContent>
        <Button variant="outline" size="sm">
          Refresh
        </Button>
      </EmptyContent>
    </Empty>
  );
}

// A solid outline instead of the default dashed border.
const styles = stylex.create({
  root: {
    borderStyle: 'solid',
  },
});

Avatar

Use EmptyMedia with our Avatar for people- or team-shaped empty states.

MD
No team members
Invite people to collaborate on this project.
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
import { Button } from '@/components/ui/button';
import {
  Empty,
  EmptyContent,
  EmptyDescription,
  EmptyHeader,
  EmptyMedia,
  EmptyTitle,
} from '@/components/ui/empty';

export default function EmptyAvatar() {
  return (
    <Empty>
      <EmptyHeader>
        <EmptyMedia>
          <Avatar size="lg">
            <AvatarImage src="https://github.com/madeui.png" alt="@madeui" />
            <AvatarFallback>MD</AvatarFallback>
          </Avatar>
        </EmptyMedia>
        <EmptyTitle>No team members</EmptyTitle>
        <EmptyDescription>
          Invite people to collaborate on this project.
        </EmptyDescription>
      </EmptyHeader>
      <EmptyContent>
        <Button size="sm">Invite members</Button>
      </EmptyContent>
    </Empty>
  );
}

Input group

Nest an InputGroup inside EmptyContent for a search-style empty state.

No results found
Try searching for a different keyword.
import {
  Empty,
  EmptyContent,
  EmptyDescription,
  EmptyHeader,
  EmptyMedia,
  EmptyTitle,
} from '@/components/ui/empty';
import { InputGroup, InputGroupAddon, InputGroupInput } from '@/components/ui/input-group';

export default function EmptyInputGroup() {
  return (
    <Empty>
      <EmptyHeader>
        <EmptyMedia variant="icon">
          <svg
            width="16"
            height="16"
            viewBox={`0 0 16 16`}
            fill="none"
            stroke="currentColor"
            strokeWidth="1.5"
            strokeLinecap="round"
            strokeLinejoin="round"
            aria-hidden
          >
            <circle cx="7" cy="7" r="5" />
            <path d={`m13.5 13.5-3-3`} />
          </svg>
        </EmptyMedia>
        <EmptyTitle>No results found</EmptyTitle>
        <EmptyDescription>
          Try searching for a different keyword.
        </EmptyDescription>
      </EmptyHeader>
      <EmptyContent>
        <InputGroup>
          <InputGroupInput placeholder="Search…" />
          <InputGroupAddon>
            <svg
              width="14"
              height="14"
              viewBox={`0 0 14 14`}
              fill="none"
              stroke="currentColor"
              strokeWidth="1.5"
              strokeLinecap="round"
              strokeLinejoin="round"
              aria-hidden
            >
              <circle cx="6" cy="6" r="4.5" />
              <path d={`m12 12-2.5-2.5`} />
            </svg>
          </InputGroupAddon>
        </InputGroup>
      </EmptyContent>
    </Empty>
  );
}

API reference

Plain layout markup. EmptyMedia accepts variant: 'default' (transparent) or 'icon' (muted rounded square for an icon). Every part accepts a style prop (StyleXStyles, merged last).

Was this page helpful?