Empty State
Fill spaces when no content has been added yet, or is temporarily empty due to the nature of the feature and should be designed to prevent confusion.
Empty state Design framework
When designed thoughtfully, empty states become an essential part of a smooth user experience, providing enough context to keep users working in a productive way. There are several approaches to explore that will match the needs a developer in different situations:
- Blank Slate - Basic empty state for first run experience
- Informational - Alternative for first use empty state, including in-line CTAs and supplemental documentation links
- Educational - Launch a contextual onboarding flow to gain deeper understanding about that area of the app
- Guide - Starter content that allows users to interact with data and learn the system by tinkering or setting up their environment
Blank slate
The most basic empty state should convey the state of the view.
Informational
Help users by clearly explaining the benefit and utility of a product or feature, with a call to action and link to more information to help users progress.
Default to showing rather than telling the value of a feature. Certain entry points to a product may call for a unique empty state and a call to upgrade. Informational empty states will include a call to action.
Best Practices
When to use
- Pick the variant by what the user needs: no-results for a filtered list that returned zero rows, blank slate or informational for a resource the user hasn’t created, cleared for completed work, permission for role or tier denials, error for a failed load.
- Render the permission and tier-denial variants full-page when the user lands on a route they can’t view. Use a Note only when one tile inside an otherwise-accessible page is gated.
- Don’t put critical persistent warnings here. Empty states vanish when the list populates; persistent warnings belong in Note or the page header.
Behavior
- The CTA must be a real Button or Link, not an
onClickdiv, so it joins the tab order and exposes a role. - Cap at one primary CTA, plus one secondary when the first action could legitimately be one of two paths (
Import RepositoryandDeploy Template). Three CTAs is a smell. - After an async filter change, wrap the region in
aria-live="polite"so screen readers announce the new state. - Don’t auto-launch a tour from the educational variant; pair
Start TourwithSkip.
Content
titleis Title Case (No Logs Match Your Filter);descriptionis sentence case and adds new information instead of restating the title.- Quote a single typed query verbatim with curly quotes:
No logs match “${query}”. Clear the filter to see all logs.For multi-facet filters use the plural templateNo {Items} Match Your Filtersand suggest widening or clearing. - Onboarding bodies name the next action that creates the first item:
Push to your Git repository to create your first one.Tier-gated bodies follow{Feature value} with the {Plan} plan. - Error variant pairs the body with a copyable request ID and a
Try Againbutton. - CTA labels are Title Case
Verb + Noun. NeverGet Started,Continue, orOK.
Was this helpful?