Skip to content

Empty states

What to show when there's nothing to show: on first use, with no results, and after errors.

An empty screen is a moment of maximum attention with minimum content. Use it to explain what belongs here and offer the next step.

No projects yet
No results for “billng”
Couldn't load deployments
import {
  FolderPlusIcon,
  RefreshCwIcon,
  SearchXIcon,
  WifiOffIcon,
} from "lucide-react"

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

export default function EmptyStates() {
  return (
    <div className="grid w-full gap-4 lg:grid-cols-3">
      <Empty variant="outline" className="p-6 md:p-8">
        <EmptyHeader>
          <EmptyMedia variant="icon">
            <FolderPlusIcon />
          </EmptyMedia>
          <EmptyTitle>No projects yet</EmptyTitle>
          <EmptyDescription>
            Create a project to deploy your first site.
          </EmptyDescription>
        </EmptyHeader>
        <EmptyContent>
          <Button size="sm">Create project</Button>
        </EmptyContent>
      </Empty>
      <Empty variant="outline" className="p-6 md:p-8">
        <EmptyHeader>
          <EmptyMedia variant="icon">
            <SearchXIcon />
          </EmptyMedia>
          <EmptyTitle>No results for “billng”</EmptyTitle>
          <EmptyDescription>
            Check the spelling or clear filters.
          </EmptyDescription>
        </EmptyHeader>
        <EmptyContent>
          <Button size="sm" variant="outline">
            Clear filters
          </Button>
        </EmptyContent>
      </Empty>
      <Empty variant="outline" className="p-6 md:p-8">
        <EmptyHeader>
          <EmptyMedia variant="icon">
            <WifiOffIcon />
          </EmptyMedia>
          <EmptyTitle>Couldn&apos;t load deployments</EmptyTitle>
          <EmptyDescription>
            You appear to be offline. We&apos;ll retry when you reconnect.
          </EmptyDescription>
        </EmptyHeader>
        <EmptyContent>
          <Button size="sm" variant="outline">
            <RefreshCwIcon data-icon="inline-start" />
            Try again
          </Button>
        </EmptyContent>
      </Empty>
    </div>
  )
}

Three kinds of empty

KindCauseOffer
First useNothing has been created yet.Explain the value in one sentence and give the primary action.
No resultsA search or filter excluded everything.Echo the query, suggest a fix, and offer to clear filters.
ErrorContent failed to load.Say what happened in plain words and offer to retry. Keep the page usable.

Guidelines

  • Use the Empty component, with an icon in EmptyMedia, a title, a one-sentence description and at most two actions.
  • Match the container. Inside a card or table, use variant="outline" and compact padding; on a full page, center it with generous space.
  • Don't blame. No results for “billng” is neutral; You made a typo is not.
  • Keep the frame. Show table headers, filters and navigation around the empty state so people keep their bearings.
  • Illustrations are optional. An icon is enough; a large illustration on every empty table becomes noise.