Guide 06 / 08
How pages should respond while loading, when empty, and on errors
Loading, no data, errors, and action results. When to use a skeleton, an empty state, or a toast, all in one place.
15 terms2 min read2 example prompts to copy
When AI writes a page, it often only covers the case where "the data comes back fine." Real users run into slow loading, no data, and API errors, and each of those screens needs its own design.
Waiting: loading states
A Loading State comes in a few forms. Pick one by situation:
- Skeleton: when a page or list loads for the first time and you know the content's shape, show gray blocks in the shape of the real content first, so the page doesn't jump when the data arrives.
- Spinner: for waits of a second or two, like waiting for the API after clicking submit, or refreshing part of the page. When the submit Button spins, it should also go into a Disabled State so it can't be clicked repeatedly.
- Progress: for long tasks like uploads and exports where you can get real progress, show a percentage. If you can't get real progress, don't fake a progress bar.
No data: empty states
When a list or table has no content, show an Empty State. Don't just write "No data." Explain why it's empty and offer a next step, like "No projects yet. Create one" or "No matches. Try clearing the filters." While data is still loading, don't flash the empty state first either.
Something went wrong: error states
An Error State should use plain words, give the reason, and offer a way forward. If one card fails to load, show "Failed to load. Retry" in that card instead of blanking the whole page. When the API errors, don't show it as "No data" either, or you'll hide the real problem.
After an action: telling users the result
- Toast: for results you can say in one sentence, like saved or copied. It disappears on its own after a few seconds.
- Alert: for status that needs to stay on the page, like an unverified account, or a summary of why a form submission failed.
- Notification: for messages pushed while the user may be doing something else, like a background task finishing or a new approval request arriving.
- Modal: only when users must make a decision before they can continue, like a Confirmation Dialog before an action that can't be undone, such as deleting.
For small actions like liking or checking off a to-do, you can use an Optimistic Update: the UI changes right away and switches back if the request fails. For deletions that can be restored, offering Undo in the toast is smoother than showing a confirmation dialog every time.
How to describe it to AI
The order list needs to handle four states. On first load, show a 5-row skeleton. With no data, show an empty state with the text "No orders yet" and a "Create one" button below it. If the API fails, show the error reason and a "Retry" button in the list area, not a full-page error. When the data is fine, show the table.
After an order is deleted, remove it from the list right away and show a "Deleted" toast with an "Undo" button, so it can be restored within 5 seconds. Only call the delete API after the 5 seconds are up.