Empty State
<div>
Shown when a data set is empty, a search returns nothing, or a feature hasn't been used yet. A good empty state explains what's missing and offers a clear action.
Overview
Preview
No files yet
Upload your first file to get started. Supports PNG, JPG, PDF up to 10MB.
No results found
No components match "datepicker". Try a different search term.
Default empty state
Preview
No files yet
Upload your first file to get started. Supports PNG, JPG, PDF up to 10MB.
html
<div class="flex flex-col items-center justify-center rounded-xl border border-dashed border-zinc-800 px-8 py-14 text-center">
<!-- Icon -->
<div class="flex h-12 w-12 items-center justify-center rounded-full bg-zinc-800/80 mb-4">
<svg class="h-5 w-5 text-zinc-500" ...></svg>
</div>
<!-- Copy -->
<p class="text-sm font-semibold text-zinc-300">No files yet</p>
<p class="mt-1 text-xs text-zinc-600 max-w-xs">
Upload your first file to get started. Supports PNG, JPG, PDF up to 10MB.
</p>
<!-- Action -->
<button class="mt-4 inline-flex items-center gap-2 rounded-md bg-[#D40C37] px-4 py-2 text-xs font-medium text-white hover:bg-[#b50a2f] transition-colors">
Upload file
</button>
</div>No search results
Preview
No results found
Nothing matched "datepicker". Try a different term.
html
<div class="flex flex-col items-center justify-center rounded-xl border border-dashed border-zinc-800 px-8 py-14 text-center">
<div class="...mb-4">
<!-- Search icon -->
</div>
<p class="text-sm font-semibold text-zinc-300">No results found</p>
<p class="mt-1 text-xs text-zinc-600">
Nothing matched <span class="font-mono text-zinc-500">"{{ query }}"</span>. Try a different term.
</p>
<button class="mt-4 rounded-md border border-zinc-700 px-4 py-2 text-xs font-medium text-zinc-400 hover:bg-zinc-800 transition-colors">
Clear search
</button>
</div>In a table
html
<table class="w-full">
<thead><!-- ... --></thead>
<tbody>
<!-- No data row -->
<tr v-if="rows.length === 0">
<td :colspan="columns.length" class="px-5 py-16 text-center">
<div class="flex flex-col items-center gap-3">
<div class="flex h-10 w-10 items-center justify-center rounded-full bg-zinc-800/80">
<svg class="h-4 w-4 text-zinc-500" ...></svg>
</div>
<div>
<p class="text-sm font-medium text-zinc-400">No records found</p>
<p class="mt-0.5 text-xs text-zinc-600">Adjust your filters or add new data.</p>
</div>
</div>
</td>
</tr>
<!-- Data rows -->
<tr v-for="row in rows" :key="row.id"><!-- ... --></tr>
</tbody>
</table>Minimal (no icon)
Preview
No notifications
You're all caught up.
html
<div class="flex flex-col items-center justify-center py-12 text-center">
<p class="text-sm font-medium text-zinc-500">No notifications</p>
<p class="mt-1 text-xs text-zinc-700">You're all caught up.</p>
</div>Writing good empty states
- Be specific — "No thumbnails downloaded yet" beats "Nothing here"
- Explain why — "Your API key hasn't been used this month" adds context
- Give a next step — a primary action button converts empty states into onboarding moments
- Don't apologise — don't say "Sorry, no results found"
- Match the context — a search empty state needs "Clear search", a first-run needs "Get started"
Accessibility notes
- Empty states are purely informational — no special ARIA is required
- If the empty state replaces a live region (like a table), ensure
aria-live="polite"is on the container so screen readers announce the state change