Empty state component for displaying when a list, table, or view has no data.
Use this component to replace empty tables, lists, or content areas with a helpful, visually consistent message that guides users toward a next action. Pure HEEx — no JavaScript required.
Slots
| Slot | Required | Purpose |
|---|---|---|
:icon | No | Leading illustration icon (e.g. <.icon name="inbox">) |
:title | Yes | Primary heading for the empty state |
:description | No | Supporting text with additional context |
:action | No | Call-to-action button, link, or other control |
Basic example
<.empty>
<:icon><.icon name="inbox" size={:lg} /></:icon>
<:title>No notifications</:title>
<:description>You're all caught up! Check back later.</:description>
</.empty>With a call-to-action
<.empty>
<:icon><.icon name="folder-open" size={:lg} /></:icon>
<:title>No projects yet</:title>
<:description>Get started by creating your first project.</:description>
<:action>
<.button phx-click="new_project">
<.icon name="plus" size={:sm} />
New Project
</.button>
</:action>
</.empty>Inside a table (colspan)
Replace the table body when there are no rows. Use colspan to span all
columns so the empty state is centred across the full table width:
<tbody>
<%= if @posts == [] do %>
<tr>
<td colspan="5" class="p-0">
<.empty>
<:icon><.icon name="file-text" size={:lg} /></:icon>
<:title>No posts published</:title>
<:description>Publish your first post to see it here.</:description>
<:action>
<.button phx-click="new_post">Write a post</.button>
</:action>
</.empty>
</td>
</tr>
<% else %>
<%= for post <- @posts do %>
<tr>...</tr>
<% end %>
<% end %>
</tbody>Search results with no matches
<.empty>
<:icon><.icon name="search-x" size={:lg} /></:icon>
<:title>No results for "{@search_query}"</:title>
<:description>Try a different search term or remove your filters.</:description>
<:action>
<.button variant={:outline} phx-click="clear_search">Clear search</.button>
</:action>
</.empty>Error / access denied state
<.empty>
<:icon><.icon name="shield-off" size={:lg} /></:icon>
<:title>Access restricted</:title>
<:description>You don't have permission to view this content.</:description>
<:action>
<.button navigate={~p"/dashboard"}>Go to Dashboard</.button>
</:action>
</.empty>
Summary
Functions
Renders a centred empty state with optional icon, title, description, and action.
Functions
Renders a centred empty state with optional icon, title, description, and action.
All slots are purely optional except :title. The layout is a vertical
flex column centred both horizontally and vertically inside the container.
Attributes
class(:string) - Additional CSS classes applied to the outer container<div>. Usemin-h-[N]to control minimum height. Defaults tonil.- Global attributes are accepted. HTML attributes forwarded to the root
<div>element.
Slots
icon- Optional leading icon or illustration. Rendered intext-muted-foregroundwith bottom margin.title(required) - Primary heading text for the empty state. Rendered as a bold<h3>.description- Optional supporting text with additional context. Rendered in muted small type, max width constrained for readability.action- Optional call-to-action area. Place a button, link, or any interactive element here.