Which Loading, Empty and Error States Should You Specify for a Business Web App?
Specify seven states for each main screen of a business web app: first use, no filtered results, loading, partial failure, expired access, saved and a general failure state. For each one, write down what the person sees, what they can do next and what the app must not do. This is a recommended shortlist for planning a project, not a universal best practice.
The decision in this article is narrow: which in between moments deserve a written description before development begins. It is not about how to lay out form fields.
Why these moments need a brief
Most specifications describe the happy path, where data exists, the network responds and the person is signed in. Real use includes blank accounts, slow connections, filters that match nothing and sessions that run out. If the brief is silent, each developer or tool fills the gap differently, and the result is a screen that looks broken or, worse, looks successful when it is not.
The seven states below are a curated starting list. Your app may need fewer, or one more that is specific to your business. Keep the list short enough that every item can actually be tested.
The seven states
1. First use
The account exists but holds no records yet. Recommendation: show a short explanation of what will appear here and one clear first action, such as adding the first client or order. Criteria: the screen does not look like an error, it names the next step, and it disappears once the first record exists.
2. No filtered results
Records exist, but the current search or filter matches none of them. This differs from first use, because the person already has data. Recommendation: say that nothing matched, show which filters are active and offer a way to clear them. The W3C explains that brief text messages about the status of a search, such as "Searching...", "18 results returned" or "No results returned", would be status updates when they do not take focus or cause a page refresh. Criteria: the no results message is distinct from the first use message and is exposed to assistive technology.
3. Loading
Data is on its way. Recommendation: show a visible waiting indicator for anything that can take noticeable time, keep the layout stable and never show the empty state while data is still loading, since that briefly tells the person their records are gone. The W3C notes that a status message can give information on the waiting state of an application. It also points out that when status text is removed, its absence may itself convey information about the status, which sighted users notice and others may not. Criteria: a loading indicator appears, ends in either data, the empty state or an error, and the end of waiting is conveyed in a non visual way too.
4. Partial failure
Some parts of a screen load and others do not, or a bulk action succeeds for some records and fails for others. Recommendation: show what worked, list what did not, and do not replace a mostly useful screen with a single blank error. Offer a retry for a failed part only when repeating it is safe. If it is unknown whether an item was processed, mark it as uncertain and check the existing result before any retry, so nothing is done twice. Criteria: the successful content stays visible, each failure names the affected item, uncertain items are labelled as such, and a retry does not repeat items that already succeeded.
5. Expired access
The sign in session has ended. This is different from a person who is signed in but lacks permission for something. Recommendation: explain that access has expired, offer sign in, and return the person to where they were afterwards when that is safe. Decide whether unsaved work is kept for a short time or lost, and say so on screen. Criteria: the brief states which protected data may remain on screen after expiry and which must be hidden, the message distinguishes expired sign in from missing permission, and the unsaved work rule is written down. Role design is a separate subject covered in the resource on access roles.
6. Saved state
The person needs to know that a change was stored. Recommendation: show a confirmation that names what was saved. The W3C gives the example of a message such as "Saved in 'Wedding' album", which is also read by a screen reader. It also lists after a form submission the text "Your form was successfully submitted." Criteria: confirmation appears only after the server accepted the change, it names the item, and it does not steal focus.
7. General failure
Something went wrong that is not covered above. Recommendation: distinguish a confirmed failure from an unknown outcome. When the server clearly rejected the action, say that it did not complete. After a timeout or lost connection the action may still have been saved, so show an uncertain state such as that the result could not be confirmed, check the existing record, and only then offer a retry. State whether entered data was kept and offer a next step such as refresh or contact. Where an input problem is detected and a fix is known, the W3C says the success criterion on error suggestion applies: suggestions for correction are provided to the user, unless it would jeopardize the security or purpose of the content. Criteria: the message avoids technical codes as the only content, says whether entered data was kept, never claims success without confirmation and never claims failure when the outcome is unknown. How duplicates from repeated attempts are prevented is a separate technical question for the developer.
How to make messages reach everyone
The W3C describes status messages as content changes that are not a change of context and that report success or results of an action, the waiting state, progress, or errors. The intent is to make users aware of changes without receiving focus. The same page warns of a risk of making an application too chatty for a screen reader user. So specify which of your seven states announce themselves and which stay quiet, and have the result checked by people, not assumed. This article does not claim any particular level of conformance for your project.
A hypothetical example
Imagine a small cleaning company that commissions an internal app to track jobs. On day one the job list is empty, so it shows a short explanation and an Add job button. After a week, the manager filters by a crew with no jobs and sees a message that nothing matched, with a Clear filters link. While the list loads, a placeholder appears instead of the empty message. One morning the job list loads but the crew panel does not, so the list stays and the panel shows a retry. Later a session expires while a note is being typed, and the app states clearly whether the note was kept. After saving, the screen says which job was saved. This is an invented illustration, not a report of a real project.
Acceptance checklist
Use this list when you write acceptance criteria for the project, and bring it to a project conversation.
- Each main screen has a written first use description.
- No results and first use are visibly different.
- Empty states never appear while loading is in progress.
- Loading ends in data, an empty state or an error, never silence.
- Partial failures keep working content visible, label uncertain items and retry only what is safe to repeat.
- Expired access follows a written policy for protected data on screen and states the unsaved work rule.
- Saved confirmations appear only after the server accepted the change.
- General failure messages separate confirmed failure from unknown outcome and say whether data was kept.
- Status messages are checked with assistive technology by a person.
FAQs
Do I need all seven states on every screen?
No. Apply them to the screens that matter most, such as lists, dashboards and anything that saves data. A simple static page may need none.
Who writes the wording of these messages?
The business should approve the wording, because it describes how the company speaks to its own staff or customers. A developer can propose a draft, but a short message list is easier to review than scattered screens.
How do I test states that are hard to trigger?
Ask for a way to simulate them in a test environment, such as an empty account, a deliberately slow response, a failing part and an expired session. Whether that is practical depends on the project, so raise it early.