Most empty state advice is too focused on visuals.
You'll see guidance about cute illustrations, friendly copy, and whether the button should say "Create" or "Get started." That stuff matters a little. But the real job of an empty state is much simpler: reduce ambiguity and make the next action obvious.
If a user lands on a blank screen and has to ask "Is this broken?" or "Am I supposed to do something?" the empty state failed, even if it looked nice.
The first thing to understand is that empty is not one state.
This is the cleanest version of empty. There is no data because the user has not created anything yet.
A project dashboard with no tasks. A CRM with no contacts. A design library with no components. In these cases the user's question is not "where did my stuff go?" It is "what is this screen for, and how do I start?"
That means the empty state should do three things:
A good first-use empty state for a task list might say:
"No tasks yet. Create your first task to start tracking work."
That is enough. It explains the absence and gives the next step. You do not need a paragraph about productivity.
The CTA also matters. If the screen is only useful after setup, the button
should move setup forward: Create task,
Import contacts, Connect Stripe,
Invite your team.
This is where people get generic. They use the same empty state everywhere because it looks clean in the component library. But the right CTA depends on what unlocks the screen.
This one gets mishandled constantly.
The screen is not empty because the user has no data. It is empty because the current filters removed all visible results. Those are very different messages, and users feel the difference immediately.
If someone has 184 orders in the system and your table says "No orders yet," you've just lied to them.
Filtered-empty states should explain the active cause:
No orders match these filtersNo teammates found for "design" in the London officeNo issues assigned to you in the last 7 daysThen the next action should undo the cause:
This is not just copy. It affects UI structure. If the filter bar is visible, the empty state can stay compact because the cause is already on screen. If the filters collapse behind a drawer or popover on mobile, the empty state may need to carry more explanation and a stronger reset action.
When people say an empty state "feels dumb," this is often what they mean. The UI knows why the list is empty but refuses to say it.
This one is easy to miss because it looks visually similar to first-use empty, but emotionally it is different.
The user had data. Now they don't.
Maybe they archived all cards in a column. Maybe they completed every task in a list. Maybe they deleted every saved view. The interface should acknowledge that change, because "nothing here yet" sounds like the product forgot what just happened.
A better message is contextual:
All tasks completedNo saved views leftYou've cleared this queue
This kind of empty state often benefits from a secondary action instead of
a primary one. If someone just completed every task, maybe the best action
is View archived or Create task, but maybe it is
no button at all. Sometimes the acknowledgment is the point.
That is an important distinction. Empty states do not always need to push creation. Sometimes they need to confirm completion.
These are where generic patterns really fall apart.
Imagine a team member opens the billing page and sees no invoices. Is that because there are none? Because billing isn't set up? Because they lack permission? Because the request failed and the app fell back to an empty array?
Those are four different product states that can all produce a blank surface if you are careless.
Permission-based empty states should say so plainly:
You don't have access to billing invoicesAsk an admin to grant accessError-adjacent empty states should not pretend emptiness is normal:
We couldn't load invoicesTry againThis matters because the next action changes completely. For permissions, retrying is useless. For transient errors, requesting access is nonsense.
If you collapse both into a soft, neutral "Nothing to show," the user now has to debug your product state from the outside.
The same empty-state content can feel right or wrong depending on where it appears.
An empty full-page dashboard can support a headline, supporting sentence, and clear CTA because the absence defines the whole screen. An empty table inside a dense admin panel usually needs a tighter treatment because the surrounding UI already provides context.
That means you should not build one empty-state component and drop it everywhere unchanged.
A useful split is:
Full-page states can teach. Inline states should mostly clarify.
The wrong layout makes interfaces feel louder than they need to. A large illustration inside a tiny filtered table is distracting. A tiny one-line message in a first-use flow feels cold and unfinished.
If you want a simple rule, every empty state should answer these three questions:
Not every answer needs a full sentence. Sometimes the screen context already answers one of them. But if the user has to infer all three, the UI is making them work too hard.
That is why generic empty states fail. They usually answer only the first question, and even that badly.
Nothing here yet is not wrong because it is short. It is
wrong because it throws away the most useful information the interface
has.
The best empty states are not memorable because they are cute. They are memorable because the user never had to wonder what was going on.