Skip to content
UI

Empty states

What to show when there is nothing to show, and how to write it so the user knows what to do next.

An empty state appears whenever a list, table, chart or panel has no content. It is a moment to explain, not a dead end: the user should always learn why the area is empty and what they can do about it.

Kinds of empty state

These look alike and are not. Each needs its own message, and often its own component.

Kind When Tell the user Component
Nothing yet First use: no data has arrived or been created What will appear here, and how to get it there List Empty State with an action
No results A search or filter matched nothing That the filters caused it, and how to widen them List Empty State with Clear filters
All done The user cleared a queue That the work is finished List Empty State, no action
Failed to load The request failed That something went wrong and that they can try again List Error State
No permission The user lacks the permission for this area That access is restricted and who can grant it The app’s access-denied state on List Empty State
Not contracted The tenant does not have the module That the module is not part of their plan The app’s module-unavailable state on List Empty State

The last three are not “no data”: showing “No alerts yet” for a failed request or a missing permission tells the user something false.

No alerts yet
Alerts appear here as soon as a connector reports a detection.
<ListEmptyState
  title="No alerts yet"
  description="Alerts appear here as soon as a connector reports a detection."
/>

Writing

  • Title: why the area is empty, in one short line, without a period. “No alerts yet”, “No assets match these filters”.
  • Description: what happens next or what to do, in one to three full sentences, with periods. “New alerts appear here as soon as a detection rule matches.”
  • Name the object (“alerts”, “assets”), not “items”, “data” or “results” when you can.
  • Keep it neutral. An empty state is not an error and not a celebration.

Actions

  • Offer an action when there is one clear next step: create the first rule, clear the filters, try again.
  • Use an outline button or a link, never the default (primary) variant: the empty state is not the main task of the page.
  • Show the action only if the user has the permission for it. Otherwise explain who can.
  • One action. Two at most when they are true alternatives (Create rule, Import rules).
No alerts match these filters
Try a wider time range or remove a filter.
<ListEmptyState
  icon={SearchXIcon}
  title="No alerts match these filters"
  description="Try a wider time range or remove a filter."
  action={
    <Button variant="outline" size="sm">
      <FilterXIcon data-icon="inline-start" />
      Clear filters
    </Button>
  }
/>

Errors

A failed request uses List Error State: it says the data could not be loaded and offers Try again. Never put the raw error message in it; log it instead.

Something went wrong
The data could not be loaded. Try again in a moment.
function ListErrorStateDemo() {
  return <ListErrorState onRetry={() => {}} />
}

Size and repetition

  • In small containers (a card, a sidebar panel), drop the icon and keep only the text.
  • When several areas of one screen are empty for the same reason (a new tenant, a filter that matches nothing), show one message for the screen instead of one per card.
  • Keep the table header visible above an empty table, so the user still sees what the table would contain.