BlogUI/UX

Empty States: A Before/After Breakdown of a Zero-Data Screen

A hypothetical invoice screen with no data, redesigned step by step. What the empty state should say, show and do, and what to hand to developers.

Denny Pratama

02 Nov 2026 · 7 min read · UI/UX

Empty States: A Before/After Breakdown of a Zero-Data Screen

Say a small invoicing app has an "Invoices" screen. A new user signs up, clicks Invoices in the sidebar, and sees this.

This is a hypothetical screen. I'm using it because empty states are the kind of thing that gets skipped in a design file and then shipped as whatever the developer, or the AI tool, happened to produce. I've seen that gap often enough in my own handoff habits to take it seriously, so let's fix one on paper.

01The "before" screen

The page has a title, "Invoices", a search box, a filter dropdown, and a table header with columns: Number, Client, Amount, Status, Due date. Below the header there is a single line of grey text: "No data."

Nothing is technically broken. But look at what the screen asks the user to do:

  • Read a table header for a table with no rows.
  • Guess why it's empty (did something fail to load?).
  • Find the "New invoice" button, which lives in the top right corner and is easy to miss.

The screen is accurate and useless. It describes the state of the database, not the state of the user's journey.

02Step 1: Decide which empty state you're designing

"Empty" is not one situation. For this screen there are at least three:

  1. First use. The user has never created an invoice.
  2. No results. The user searched or filtered and nothing matched.
  3. Cleared. Everything was paid, archived or deleted, and the list is empty again.

The "before" screen treats all three the same. That's the root problem. A person who just signed up and a person whose search for "Acme" returned nothing need different help.

I'd start with first use, because it's the one every user sees, once, at the moment they're deciding whether the product is worth their time.

03Step 2: Remove what doesn't belong

An empty table header, a search box and a filter dropdown all suggest there's something to search and filter. There isn't. Hide them.

This is a small change with a big effect. The screen goes from looking like a broken table to looking like a deliberate page. Fewer controls also means the one useful action stands out.

One caution: keep the page title and any navigation. The user should still know where they are.

04Step 3: Write a message that does three jobs

A good first-use message answers three questions in order:

  • What is this place?
  • Why is it empty?
  • What do I do next?

For our invoice screen:

Invoices you send will show up here Create your first invoice to track what's been sent, paid and overdue. [Create invoice]

Compare that to "No data." The headline says what the screen is for. The line below says what you'll get from it. The button names the action in the same words the user would use.

A few writing choices worth noting:

  • The headline is a statement, not an apology. "You have no invoices" is true but flat.
  • The button says "Create invoice", not "Get started" or "Add". Specific labels reduce hesitation.
  • There's no exclamation mark or cheerful illustration doing the work the words should do.

05Step 4: Give the action the right weight

In the "before" version the primary action sat in the corner. In the "after" version, the same action appears in the centre of the empty area as the primary button.

Should the corner button stay? I'd keep it, for consistency. When the list fills up, that's where users will look. Two buttons doing the same thing on one screen is fine here because they're serving different states, but make sure they trigger exactly the same flow.

If you have a useful secondary path, add it as a text link below the primary button. For an invoicing app that might be "Import from a spreadsheet". One secondary option is plenty. Three links turns the empty state into a menu.

06Step 5: Design the other two states

No results

The user typed "Acme" and nothing matched. Now the search box and filters must stay, because the user needs them to recover.

No invoices match "Acme" Check the spelling, or try a different client name. [Clear search]

If filters are active, name them and offer one-click removal. The worst version of this screen is one where the user can't tell whether the list is empty or whether a filter they forgot about is hiding everything. I covered related problems in Search and Filter UX: Four Mistakes That Make a Fast UI Feel Broken.

Cleared

Say the user has paid and archived everything. This is a good moment, not an error.

Nothing outstanding All your invoices are paid or archived. [Create invoice] [View archived]

Here the tone can be lighter, but still plain. The message confirms the good news and keeps the next step handy.

07Step 6: Don't confuse empty with loading or failed

There's a fourth situation that often gets lumped in: the list isn't empty, it just hasn't arrived yet, or the request failed.

If the screen flashes "Invoices you send will show up here" for half a second before real data appears, the user briefly believes their invoices are gone. That's alarming and it's a very common bug.

So the states are separate:

  • Loading: show a skeleton or spinner. Never the empty message.
  • Error: say it failed and offer a retry.
  • Empty: only after the data has loaded and is truly zero.

I wrote about the failure side of this in Designing Loading and Error States for AI Features. The principle applies to any screen that fetches data.

08What to hand to developers

Because I'm now building some of my own designs with AI tools, I've learned that if a state isn't specified, it doesn't get built. So for this screen, the handoff would list:

  • Three empty variants, each with exact copy.
  • Which controls are visible in each (search and filters hidden on first use, visible on no results).
  • The rule for when each appears: first use means zero invoices ever, no results means zero matches with an active query or filter.
  • A note that loading and error states must never show empty copy.
  • Which button is primary, and that both "Create invoice" buttons open the same flow.

That is a short list. It takes ten minutes to write and it prevents the "No data." screen from shipping.

09A quick checklist

  • Can a new user tell what this screen is for?
  • Is there one obvious next step?
  • Are controls that can't work yet hidden?
  • Do first-use, no-results and cleared states have different copy?
  • Can the screen ever show empty copy while loading?
  • Is the message readable by screen readers as real text, not baked into an image?

An empty state is the first real conversation your product has with a user. "No data." is a very short, very cold way to start it.

10Frequently asked questions

What is an empty state in UI design?

An empty state is what a screen shows when there is no content to display yet. That can be a first-time user with no data, a search with no results, or a list the user has cleared. It's an opportunity to explain the screen and point to the next step.

How many kinds of empty states should I design?

At least three: first-use (nothing created yet), no results (a search or filter matched nothing), and cleared or completed (the user finished everything). They need different messages and different actions, so one generic "No data" screen rarely works for all of them.

Should an empty state always have a button?

Not always. If the user can create the missing thing, a clear primary action helps. If the data comes from somewhere else, like an integration or another person, explain that instead and offer a way to check or learn more rather than a button that does nothing useful.

UI/UX

Denny Pratama

Product designer in Indonesia. Since 2018 I’ve designed SaaS products, dashboards and marketing sites, and now I build my own designs too.

About me