All articles
Design & UXJune 16, 2026 6 min read

Empty States Are Your Best Onboarding Surface — Stop Wasting Them

Most empty states show a sad cloud and a 'No data yet' label. That's a dead pixel. Here's how to turn the zero state into the most persuasive screen in your product.

Empty States Are Your Best Onboarding Surface — Stop Wasting Them

The first time a user opens your dashboard, they don't see your beautiful charts. They see nothing. That nothing — the empty state — is the single most under-engineered screen in most SaaS products, and it's quietly killing activation.

We've audited a lot of products in the last two years, and the pattern is depressingly consistent: teams spend weeks polishing the populated state, then ship a grey illustration and the words "No items yet" for the zero state. That screen is doing 80% of the persuasion work on day one. Let's fix it.

Why the empty state matters more than your landing page

By the time a user sees an empty state, they've already signed up. They've given you an email, maybe a credit card, definitely attention. They are leaning in. The landing page's job was to get them through the door. The empty state's job is to get them to the first valuable action — what product folks call the aha moment.

If the empty state says "No projects yet," you've handed the cognitive load back to the user. They have to guess what a project is, why they'd want one, and how to make one. Most won't bother. They'll close the tab and add your product to the mental pile of things they'll "check out later."

The three empty states people confuse

Not all empty states are the same. Treating them identically is the first mistake.

  • First-use empty: the user has never had data here. This is an onboarding surface.
  • User-cleared empty: the user archived, deleted, or filtered everything out. This is a confirmation surface.
  • Error-adjacent empty: data failed to load or permissions are wrong. This is a recovery surface.

Each needs different copy, different actions, and a different emotional register. A reassuring "Inbox zero — nice work" is delightful after the user archives their last ticket. It's bewildering on day one when they've never had a ticket at all.

What a first-use empty state actually needs

For the first-use case — the high-leverage one — there are four jobs the screen has to do, in order:

  1. Name the value. Not the feature. "Track which deals are stalling" beats "Your pipeline is empty."
  2. Show the shape of success. A muted preview, a ghost row, a screenshot of what populated state looks like. Users need a mental model before they'll invest effort.
  3. Offer one obvious next action. Not three. One primary CTA, maybe one secondary escape hatch (import, sample data, watch a 30-second demo).
  4. Remove the blank-page tax. If you can pre-seed sample data they can poke at and then delete, do it. Friction at zero is a churn multiplier.

The "ghost row" pattern

One of the highest-ROI changes we've shipped for clients is replacing the centered illustration-and-button layout with a ghost row — a low-opacity version of what a populated row would look like, with a CTA inline.

It works because the user immediately understands the structure of the page. They see columns, they see what a record looks like, they see where the action lives. The abstract "add your first project" button gives way to a concrete "this is what you're building toward."

function ProjectsTable({ projects }: { projects: Project[] }) {
  if (projects.length === 0) {
    return (
      <div className="rounded-lg border">
        <TableHeader />
        <div className="relative">
          {/* Ghost row — visually present, semantically hidden */}
          <div
            aria-hidden="true"
            className="opacity-30 pointer-events-none select-none"
          >
            <TableRow
              name="Acme website redesign"
              owner="Sam"
              status="In progress"
              updated="2 hours ago"
            />
          </div>
          <div className="absolute inset-0 flex items-center justify-center">
            <div className="text-center max-w-sm">
              <h3 className="font-medium">Track work that's actually moving</h3>
              <p className="text-sm text-muted-foreground mt-1">
                Projects let you group tasks, assign owners, and see what's stalled.
              </p>
              <div className="mt-4 flex gap-2 justify-center">
                <Button onClick={createProject}>Create a project</Button>
                <Button variant="ghost" onClick={loadSampleData}>
                  Use sample data
                </Button>
              </div>
            </div>
          </div>
        </div>
      </div>
    );
  }

  return <PopulatedTable projects={projects} />;
}

A few things to notice. The ghost row is aria-hidden because it's decorative — screen readers should hit the heading and CTA directly, not a fake row. The sample data button is a graceful escape for users who aren't ready to commit. And the copy talks about outcomes ("what's stalled"), not features ("task management").

Copy rules that survive translation

Empty state copy is where designers and PMs fight, and the fight usually produces something committee-shaped. A few rules we lean on:

  • No apologies. "Oops, nothing here yet!" infantilises the user. They know it's empty.
  • No metaphors that don't localise. "Your inbox is squeaky clean" is charming in English and meaningless in seven other languages.
  • Verb-first CTAs. "Create project" beats "Get started" because it tells the user what's about to happen.
  • One sentence of value, one sentence of how. That's it. Three paragraphs of marketing copy on an empty state is a confession that your product isn't obvious.

When humour works and when it doesn't

Humour in empty states is a power move, and like most power moves, it's mostly wrong. It works when the empty state is a celebration (inbox zero, all tasks done) because the user's emotional state can absorb levity. It fails on first-use empties because the user is mildly anxious and trying to figure out if they made the right choice signing up. Comedy on top of anxiety reads as glib.

Instrumenting empty states

If you ship a new empty state and don't measure it, you've just done decoration. The minimum useful instrumentation:

  • View event when the empty state renders, with a variant property (first-use, cleared, error).
  • Click events on every CTA including secondary ones.
  • Time-to-first-action: how long from empty-state-view to the user creating their first real record.
  • Sample-data conversion: of users who loaded sample data, how many created something real within seven days.

In our experience, moving a first-use empty state from "illustration plus button" to "ghost row plus inline CTA plus sample data" tends to lift first-action rates noticeably — often in the range of 15–30% — though the absolute number depends heavily on how complex the underlying object is. A project is harder to create than a note.

Accessibility traps to avoid

Empty states are a common accessibility blind spot because they're often built as one-off components outside the design system.

  • The empty state heading should be a real <h2> or <h3> that fits the page's heading order, not styled <div> text.
  • Decorative illustrations and ghost rows need aria-hidden="true" so screen readers skip them.
  • The primary CTA must be reachable by keyboard with a visible focus ring — yes, even when it's the only interactive element on the page.
  • Don't rely on colour alone to signal that something is a placeholder. Low-opacity grey ghost rows can hit contrast issues; pair them with explicit copy or an aria-label on the container that says "No projects yet."

A checklist before you ship

Before an empty state goes to production, run it through this:

  • Does it name a user outcome, not a feature?
  • Is there exactly one primary action?
  • Is there a low-commitment escape hatch (sample data, import, demo)?
  • Does the user-cleared variant differ from the first-use variant?
  • Is the heading a real semantic heading?
  • Are decorative elements aria-hidden?
  • Are you tracking view, click, and time-to-first-action?

If any of those are "no," you've got a dead pixel where your best onboarding surface should be.

Where we'd start

If you're staring at a product with twenty empty states and limited time, don't redesign them all. Pull the analytics, find the three empty states with the highest first-session view counts, and rebuild those first — almost always the main list view, the dashboard, and whatever the second-tab navigation lands on. Ship the ghost-row pattern, add sample data, write outcome-focused copy, and measure time-to-first-action for two weeks. That's usually where the activation lift hides, and it's a week of work, not a quarter.

If you want a hand auditing yours, our team does this kind of work on the product design and UX side regularly — the patterns are boring, but the impact rarely is.

#UX#Design Systems#Onboarding#SaaS

Want a team like ours?

72Technologies builds production software for the kind of teams who actually read this blog.

Start a project