---
title: "The Forgotten Screens: Empty States, Loading States and Error Pages"
url: "https://insideuxdesign.com/en/blog/the-forgotten-screens-empty-states-loading-states-and-error-pages"
language: "en"
description: "Empty lists, loading indicators and error pages that help people move on: patterns, before-and-after examples and a checklist. Design the forgotten screens."
published: "2026-04-15T09:00:00+02:00"
updated: "2026-10-15T00:39:57+02:00"
---

# The Forgotten Screens: Empty States, Loading States and Error Pages

Empty lists, loading indicators and error pages often decide whether people keep going or give up. Here is how these states can show the way instead of leaving a void, explained step by step with an invoicing tool.

In the design process, almost every screen gets its big moment. The dashboard with nice charts, the list with twenty neatly formatted items, the detail page with all the data. In the prototype, everything is always there, always fast and always error-free.

Reality looks different. When you open a new tool for the first time, you have no data yet. When you search, sometimes you find nothing. The train loses its connection, the server stops responding, an old link leads nowhere. These are exactly the moments that decide whether people keep going or give up. And these are exactly the screens that often get designed just before launch, or not at all. Then development fills them with a grey “No data” and a default spinner.

This article covers the three big groups of forgotten screens: empty states, loading states and error pages. To keep things concrete, one example runs through the whole text: an invoicing tool for freelancers. It has an invoice list, client management, a search, a CSV import for bank statements and a dashboard showing revenue. In the starting version, the empty invoice list shows only a table header without rows, the same spinner turns everywhere while loading, and errors end with “Something went wrong”.

## Why these states get forgotten so often

Design teams usually work with the so-called happy path, the route on which everything works. Mockups contain realistic but full sample data. There is rarely a dedicated frame in the design file for the moment a list is empty or a request fails.

On top of that, there is a perception problem: empty states, loading states and errors are seen as exceptions. They are not. Every new user sees empty lists first. Every page loads, sometimes quickly, sometimes slowly. And every application has errors. The only question is how they show up.

A simple countermeasure is to sketch four states for every important screen from the start: full, empty, loading and error. If you think about this at the wireframe stage, you avoid hectic workarounds later. In the invoicing tool, this means the invoice list gets four frames instead of one.

## Empty states: emptiness is an opportunity

An [empty state](https://insideuxdesign.com/en/glossar/empty-state) is the state of a screen that has no content (yet). The Nielsen Norman Group (NN/g) describes three jobs a good empty state can do: it communicates system status, it helps people understand the product, and it offers a direct path to key tasks. A blank screen saying “No entries” does none of these.

It is important to note that not all empty is the same. Depending on the cause, the screen needs a different message.

### First use: when nothing is there yet

The most common case: someone has just signed up and opens the invoice list for the first time. Here, the empty state is part of [onboarding](https://insideuxdesign.com/en/glossar/onboarding), the introduction to the product. It should answer three questions: What belongs here? Why is it empty? And what is the first step?

> **Before:** An empty table with the columns “No.”, “Client”, “Amount”, “Status” and the text “No data available” below it.
> 
> **After:** “Your invoices will appear here. You haven’t created any yet. Create your first invoice, it takes about two minutes.” Below it, a button “Create first invoice” and a text link “Import existing invoices”.

The difference is not in the visual design but in the attitude. The before version describes the state of the database. The after version describes what the person can do next. Short, action-oriented texts like these are called [microcopy](https://insideuxdesign.com/en/glossar/microcopy).

A few design rules for the first-use empty state:

- **Exactly one primary action.** Two or three equal buttons side by side just hand the decision back to the person.
- **Hint at the structure.** A heavily faded preview of what a finished invoice list will look like aids understanding. But it must be clearly recognizable as a preview and must not look like real data.
- **Use illustrations sparingly.** A friendly graphic is fine as long as it doesn’t push the text and button below the fold. On small screens, the action matters more than the illustration.
- **Sample data only with an exit.** Some tools fill new accounts with demo content. That can help people learn, but it needs clear labeling and an easy way to delete the samples. Otherwise someone ends up sending a demo invoice by accident.

### No results: when a search comes up empty

A completely different case is an empty results list. The person searched or filtered, and nothing matches. A guide to the first step is out of place here. What’s needed is an explanation of why nothing was found and a way back to results.

> **Before:** “0 results”
> 
> **After:** “No invoice found for ‘Miller Ltd’ in March 2026. The filter ‘Unpaid invoices only’ is active.” Below it, the buttons “Reset filters” and “Search all periods”.

The after version repeats the search term so typos stand out. It makes active filters visible, because forgotten filters are one of the most common reasons for empty results. And it offers concrete ways out. Good search features go one step further and suggest similar spellings (“Did you mean Muller Ltd?”) or show related results.

For people who use a [screen reader](https://insideuxdesign.com/en/glossar/screen-reader), one detail matters: the message about the number of results, including “No results”, should be announced without moving focus. The WCAG, the international guidelines for accessible web content, require this in success criterion 4.1.3 (“Status Messages”) at level AA. The W3C’s explanatory document gives exactly this example: after a search, “5 results returned” appears and is announced by the screen reader. Technically, one way to do this is a region with `role="status"`.

### All done: the positive empty state

Sometimes emptiness is a success. The invoicing tool has an “Overdue invoices” view. If nothing is there, the person has everything under control. A plain “No entries” wastes that moment.

> **After:** “No overdue invoices. All your clients have paid on time.” Below it, a subtle link “Go to open invoices”.

States like this can include a small piece of positive feedback, such as a checkmark icon. Over-the-top confetti animations, on the other hand, wear off quickly, especially in views people open every day.

### No access or removed

The fourth case is often mistaken for an error: the content exists but isn’t visible to this person. For example, because a team member only has read access or a client has been archived. Here, too, a clear sentence helps more than an empty area: “This client list is only visible to admins. Ask someone with admin rights for access.” That way, nobody is left wondering whether the data is lost or just hidden.

## Loading states: waiting without doubting

Waiting itself is rarely the problem. It gets difficult when it’s unclear whether anything is happening at all. For decades, NN/g has referred to three response time limits that Jakob Nielsen described in his 1993 book “Usability Engineering”:

- **About 0.1 seconds** feels like an instant reaction.
- **About 1 second** keeps the flow of thought intact, even though the delay is noticeable.
- **About 10 seconds** is the limit for keeping attention on the task. After that, people’s minds wander or they switch to something else.

These limits tell you which kind of loading indicator fits when.

### The right indicator for the right wait

In its article on progress indicators, NN/g recommends a clear scale. Every action needs immediate visible feedback so it’s clear the click registered. A dedicated loading indicator is worthwhile from about one second. For waits of roughly 2 to 10 seconds, a looped animation such as a spinner works. From about 10 seconds, an indicator should show how far along the process is, ideally with a percentage or a time estimate. For very long processes, a way to cancel belongs there too.

How much this matters is shown by a study from the University of Nebraska-Lincoln that NN/g refers to: people who saw a continuously animated progress indicator were willing to wait about three times longer on average than people who saw no indicator at all.

Below one second, on the other hand, a loading indicator tends to be distracting. A spinner that only flashes briefly feels jittery. In practice, a small delay helps: the indicator only appears once loading takes longer than a moment.

### Skeleton screens, spinners and progress bars

A skeleton screen is a placeholder that anticipates the structure of a page: grey blocks where headings, images and lines of text will later appear. NN/g classifies the three common patterns like this:

- **Skeleton screens** suit full-page loads that stay under about 10 seconds.
- **Spinners** fit single modules, such as a dashboard tile or a video.
- **Progress bars** are the right choice for anything that takes longer, and for processes that aren’t page loads, such as uploads, downloads or file conversions.

NN/g also points out limits. Skeletons that only show a header, footer and blank space convey no structure and look more like a broken page. Pulsing or shimmering animations can be distracting and cause problems for some people. And a skeleton screen is no substitute for faster loading.

In the invoicing tool, the split looks like this:

- **Dashboard on open:** a skeleton with four tiles and a chart area in the real layout. Each tile replaces its placeholder as soon as its data arrives, instead of the whole page waiting for the slowest query.
- **Generating an invoice PDF:** the button shows a small spinner and the text “Creating PDF”. It is disabled during this time so a second click doesn’t create a second file.
- **CSV import of bank statements:** a progress bar with concrete text: “Matching transaction 340 of 1,200”. The person can leave the window and gets a notification when the import is done.

### Optimistic interfaces

Some actions don’t need a visible loading state at all. When someone marks an invoice as “paid”, the interface can show the new status immediately and save the change in the background. This pattern is called optimistic UI. It feels fast, but only works if failures are handled cleanly: the status reverts, and a message explains that the change wasn’t saved. For high-stakes actions, such as sending an invoice to a client, the pattern is unsuitable. There, the interface should only confirm what has actually happened.

Small feedback like a briefly highlighted checkmark after saving belongs to the family of [microinteractions](https://insideuxdesign.com/en/blog/what-are-microinteractions-and-how-to-use-them). They make the status of an action visible without needing a dedicated loading indicator.

### Accessible loading

For many people, a spinner is a clear signal. For screen reader users, it is invisible unless it is announced technically. WCAG success criterion 4.1.3 applies here too: status messages like “Loading” or the progress of an upload must be available to assistive technologies without moving focus. The W3C’s explanatory document mentions, among other things, a progress bar whose status is announced at intervals.

For the animations themselves, there is good news: WCAG success criterion 2.2.2 (“Pause, Stop, Hide”) normally requires a way to pause moving content that runs for more than five seconds. According to the W3C’s explanation, however, a loading animation counts as essential if no interaction is possible during loading and leaving it out would make the page seem frozen. It is still worth reducing motion when the operating system is set to “reduce motion”. In CSS, you can check this with the `prefers-reduced-motion` media query and, for example, replace a shimmering skeleton with a calm, static area.

## Error pages: when something goes wrong

Error pages are the third group of forgotten screens. This is not about messages on individual form fields, but about states in which an entire screen or area doesn’t work. How to word a single error message well is a topic of its own. Here, the question is what happens on screen when the content itself is missing.

All error pages share a common framework. They say in plain language what happened. They don’t blame the person. They offer at least one concrete way forward. And they keep the site’s navigation so nobody ends up in a dead end.

### 404: the page doesn’t exist

A classic: someone clicks a link in an old email to an invoice that has since been deleted. The server returns status code 404 (“Not Found”). Many error pages leave it at a big “404” and a joke.

> **Before:** “404. Nothing here. Maybe aliens abducted this page.”
> 
> **After:** “This invoice no longer exists. It may have been deleted, or the link is incomplete.” Below it, an invoice search field and the links “Go to invoice list” and “Go to dashboard”.

Humor isn’t forbidden, but it must never replace orientation. Someone looking for an important invoice will find an alien punchline more annoying than charming.

There is also a technical trap that matters for search visibility. A nicely designed error page still has to return the real status code 404 (or 410 for permanently removed content). If the server returns code 200 instead, meaning “all good”, while only showing an error text, Google calls this a soft 404. According to Google Search Central, Search Console then reports such pages as errors.

### 500 and 503: the system is at fault

With server errors (status codes 500 and up), the person did nothing wrong. The page should say so. What also matters is what happens to the work they were in the middle of.

> **Before:** “Error 500: Internal Server Error. Request failed.”
> 
> **After:** “That didn’t work on our end. Your invoice has been saved as a draft. Please try again in a few minutes.” Below it, a “Try again” button and a link to the service’s status page.

For planned maintenance, there is status code 503 (“Service Unavailable”). According to MDN Web Docs, it should be sent with a user-friendly page that explains the problem. The HTTP header `Retry-After` can state when the service is expected to be back. For people, the same information belongs in the text: “We’re carrying out maintenance. The invoicing tool will be available again from around 6 a.m.” MDN also notes that such responses usually shouldn’t be cached, so nobody keeps seeing the old error page after maintenance is over.

### Offline and partial failures

Not every error affects the whole page. In the invoicing tool, the dashboard can load while only the tile with bank transactions can’t connect to the bank. In that case, it’s better to show the error exactly where it occurs: “Bank data couldn’t be loaded. Try again.” The other tiles remain usable. A full-screen error page for a single module would needlessly hide working content.

The same applies when the internet connection drops. Instead of a blank screen, the app shows the most recently loaded data with a clear note: “You’re offline. You’re seeing data as of 2:32 p.m. Changes will be saved once you’re back online.” That way, the person can keep working and knows what they can rely on.

### Never lose input

The worst error case isn’t the error itself, but lost work. Anyone who has spent ten minutes on an invoice with twelve line items and then faces an empty form after a server error will quickly lose trust in the product. That’s why error pages and error states should, wherever possible, never discard input. Local caching, automatic drafts and a “Try again” that resends the data already entered are more effective here than even the friendliest wording.

## Shared principles for all states

As different as empty lists, loading indicators and error pages are, they follow the same principles.

**Show the status.** Each of these screens answers the question “What’s going on here?”. Empty because new? Empty because filtered? Loading? Broken? If people can’t tell the difference, they guess, and they often guess wrong.

**Offer a way forward.** A state without an action is a dead end. Whether it’s “Create first invoice”, “Reset filters” or “Try again”: each of these screens gets at least one concrete next step.

**A shared language.** If every area uses its own wording and graphics for empty states, the product feels patched together. A design system can provide fixed components for this: an empty state with slots for heading, text, primary action and optional graphic, a skeleton kit and an error page template. The texts themselves still need to fit their context.

**Make them visible in the design file.** For every important view, create the four states full, empty, loading and error as separate frames. At handoff to development, a short table showing which error cases trigger which view helps.

**Test them on purpose.** These states are easily overlooked in usability tests because the test environment is full of data and loads quickly. So plan tasks that deliberately lead into an empty or error state, such as a search with no results or working with a fresh account. Many browser developer tools can also simulate slow connections or offline mode. That lets you quickly check how loading states feel on a poor connection.

## Conclusion

In the end, the invoicing tool looks very different at its edges. The empty invoice list explains what belongs there and leads to the first invoice with a single button. A search with no results shows the search term, the active filters and two ways out. The dashboard loads with a skeleton in the right structure, the CSV import with an honest progress bar. A dead link leads to a page with search and navigation, a server error says the draft is safe, and the offline notice states how current the data is.

None of these screens will get much attention in a presentation. That’s exactly why the effort pays off: these are the moments of greatest uncertainty, and a clear sentence with the right button makes the difference between carrying on and giving up.

## Checklist

- Every important view has designs for the full, empty, loading and error states.
- Empty states distinguish between first use, no results, “all done” and missing access.
- Every empty state explains what belongs there and offers exactly one primary action.
- Empty search results show the search term, active filters and a way back to results.
- Every action gives immediate feedback, loading indicators appear only after about one second.
- Spinners for single modules, skeleton screens for full pages, progress bars from about 10 seconds and for uploads or imports.
- Status messages like “Loading” or “No results” are announced to screen readers.
- Animations respect the “reduce motion” setting.
- Error pages say in plain language what happened and keep the navigation.
- 404 pages return the real status code, maintenance pages return 503 with a time estimate.
- Partial failures are shown in the affected module, not full screen.
- No error state discards input.

## Sources

- [Nielsen Norman Group: Designing Empty States in Complex Applications: 3 Guidelines](https://www.nngroup.com/articles/empty-state-interface-design/)
- [Nielsen Norman Group: Response Times: The 3 Important Limits](https://www.nngroup.com/articles/response-times-3-important-limits/)
- [Nielsen Norman Group: Progress Indicators Make a Slow System Less Insufferable](https://www.nngroup.com/articles/progress-indicators/)
- [Nielsen Norman Group: Skeleton Screens 101](https://www.nngroup.com/articles/skeleton-screens/)
- [W3C: Understanding Success Criterion 4.1.3: Status Messages](https://www.w3.org/WAI/WCAG22/Understanding/status-messages)
- [W3C: Understanding Success Criterion 2.2.2: Pause, Stop, Hide](https://www.w3.org/WAI/WCAG22/Understanding/pause-stop-hide)
- [Google Search Central: How HTTP status codes, and network and DNS errors affect Google Search](https://developers.google.com/search/docs/crawling-indexing/http-network-errors)
- [MDN Web Docs: 503 Service Unavailable](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/503)
