Users should never stare at a blank screen wondering if the app crashed. Model async work with explicit loading, data, and error branches in your template—often with v-if / v-else-if chains.
State machine mindset
- Idle / loading — spinner or skeleton
- Success — render the list or detail
- Error — message + retry button
Retry pattern
Extract fetch logic into a function you can call from onMounted and from a “Try again” button. Reset error before each attempt so stale messages do not linger.
Accessibility
Announce loading with aria-busy on the container and tie error text to the region with role="alert" when appropriate.
Self-check
- Why show error UI instead of only
console.error? - When should skeletons beat spinners?
Challenge
Simulated failure
- Toggle the “Fail request” checkbox and click Retry.
- Confirm error text appears and clears on success.
Done when: UI switches between loading, error, and data states predictably.