JM Family Design System
Patterns

Empty State

The moment a user opens a screen and finds nothing: a brand-new feature, a filter that excluded everything, or an inbox they just cleared. Empty states are teaching surfaces, not failure modes.

When to use it

Empty means the product knows there is nothing to show. It is not a loading state, an error state, or a permissions message.

Use an empty state when

  • The surface is genuinely emptyThere are no records, tasks, files, messages, vendors, or results to show for the current view.
  • The user can recover or move forwardA next action exists: create the first item, import content, clear filters, change the query, or restore context.
  • The absence needs interpretationThe user might wonder whether the product is broken, whether their action succeeded, or what would normally live here.

Use something else when

  • Data is still loadingUse a loading or skeleton state while retrieval is in progress. Do not show an empty state until the system knows there is nothing to display.
  • The system failedUse an error state or Alert when the product could not retrieve data. Empty means absence, not failure.
  • The user lacks accessUse an authorization or permissions message when content exists but the user cannot view it.

Anatomy

Five named parts. The headline and body are non-negotiable; actions depend on the type of empty state.

  • Visual anchor

    Required

    An icon or illustration that names the surface, such as an inbox, folder, or filter. Decorative only; the text must carry the meaning.

    Use an existing Icon and mark it aria-hidden.

  • Headline

    Required

    One short line that says what state the user is looking at. Use "No vendors yet," not "No data."

    Name the missing object in the user's vocabulary.

  • Body

    Required

    One or two sentences that explain what would live here once it exists and how it gets there.

    Keep the body instructional, not promotional.

  • Primary action

    Conditional

    Required for first-run states. For no-results, the primary action is usually "Clear filters" or the nearest equivalent.

    Use a verb-object label the user recognizes.

  • Secondary affordance

    Optional

    A link to documentation, a sample, or a way to switch views. Only include it when it changes what a user would do next.

    Do not add a secondary link just to fill space.

Variants

Pick the type first. A first-run surface, a failed filter, and an emptied inbox all look similar, but they are solving different user questions.

First-run

The user has never created or received anything here.

Trigger: A new account, a new feature, or a new tab the user is opening for the first time.

Job: Teach what would live here, then make the first action obvious.

No-results

The user's filter, search, or query returned nothing.

Trigger: A search box with no hits, a filter that excludes everything, or a date range with no entries.

Job: Acknowledge the query, suggest how to broaden it, and give a way back to the full view.

Absent

The user had things here and now they do not.

Trigger: Everything was archived, deleted, completed, or moved.

Job: Confirm what happened and how to recover or restore if relevant.

Examples

Render the same anatomy against different product contexts, then review the copy against the wrong/right pairs.

Vendor watchlist

No vendors on your watchlist yet

Add vendors you want to track. You will see their status, insurance, and recent jobs here.

Vendor search

Nothing matched "acme corp"

Try a shorter query, check the spelling, or clear filters to see all vendors.

Completed approvals

No completed approvals

Approvals you finish will appear here for 90 days. Open requests stay in the Pending tab.

Vendor watchlist, first-run

Wrong

No data

There are no items to display.

Right

No vendors on your watchlist yet

Add vendors you want to track. You will see their status, insurance, and recent jobs here.

Add a vendor

"No data" treats the user as a database. The right version names what would be here, why it matters, and gives the first action.

Search returned nothing

Wrong

No results found

Your search did not match any records.

Right

Nothing matched "acme corp"

Try a shorter query, check the spelling, or clear filters to see all vendors.

Clear filters

The right version echoes the query so the user knows the search ran, names two concrete ways to broaden it, and offers the escape hatch.

Voice and content

Empty states are where Voice & Tone meets product context. Four rules carry most of the weight.

  • Name what would be here

    The headline says what kind of content the surface holds. "No vendors yet" works because the user knows what a vendor is in this app. "No data" works for nobody.

  • Teach in the body, do not lecture

    Explain what the surface is for in one or two sentences. Skip apologies, marketing language, and motivational filler.

  • Make the primary action recognizable

    "Add a vendor" beats "Get started." Lead with the object the user is working with. For no-results, "Clear filters" beats "Reset."

  • Do not blame the user

    A failed filter is not a user error. "Nothing matched" beats "Your search returned no results." Stay neutral and offer the path forward.

Accessibility

Empty states are heard as well as seen. The icon is decorative; the structure carries the meaning.

  • Heading structure

    The headline is a real heading at the right level for the surrounding page, usually H2 or H3. Do not use a styled paragraph and skip the semantic.

  • Decorative visual anchor

    The icon or illustration carries no information by itself. Use aria-hidden so screen readers skip it; the headline and body must stand alone.

  • Focus order

    When an empty state replaces a populated view, the primary action should be the next focusable element after the surface heading. Do not force focus into the empty state on render.

  • Live regions for async retrieval

    For no-results after search or filtering, announce the changed result state with a polite live region. Do not use role="alert" unless the absence is urgent.

Implementation notes

The pattern composes existing primitives. A coding agent should reuse the system pieces below before introducing anything new.

  • Compose existing primitives

    An empty state is a composition of Icon, a semantic heading, paragraph text, and Button or Link for actions. No new primitive ships with this pattern.

    Primitives: Icon, Button, Link

  • Choose the wrapper from context

    For surfaces that already use Panel, keep the empty state inside the same panel. For full-page empties, no extra panel is needed because the page layout already provides the frame.

    Primitives: Panel

  • Use layout tokens for spacing

    Use stack, inset, and section-gap tokens for vertical rhythm. Do not hardcode pixel values to center the surface.

Review checklist

Use this as the acceptance gate before approving an empty state in product work.

  • The headline names the missing object, not the database condition.
  • The body explains what normally appears here.
  • The primary action is specific and recoverable.
  • The empty state is not standing in for loading, error, or permission states.
  • The icon is decorative and the heading/body carry the meaning.