Vue 3 Suspense and Async Components in Practice

Suspense lets you handle async setup() functions and async components with a single fallback boundary. Here's how to use it without overcomplicating things.

Richard GamoraRichard GamoraFullstack developer·4 min read
VueAsyncSuspense

Vue 3's <Suspense> component is still considered experimental, but it is stable enough that I use it in production for one specific pattern: components that need to fetch data during setup() before they can render.

Why this matters

Without Suspense, every component fetches its own data, manages its own loading state, and renders its own spinner. That is fine for one component but tedious when several siblings all wait on different fetches. Suspense gives you one fallback for an entire subtree.

How it looks

html<template>
  <Suspense>
    <template #default>
      <UserDashboard />
    </template>
    <template #fallback>
      <div>Loading dashboard…</div>
    </template>
  </Suspense>
</template>

Inside UserDashboard, the setup() function can be async and fetch data directly. Suspense waits for the async setup to resolve, then renders the default slot. Until then, it shows the fallback.

Where it shines

Pages that aggregate data from several places — a user profile that needs the user, their recent activity, and their saved items — benefit. Each child component fetches its own piece, Suspense waits for all of them, and the user sees one loading state instead of three staggered spinners.

Where to keep regular fetching

If a component takes user input and fetches in response (search, filters), Suspense is the wrong tool. The component is interactive — it should manage its own loading state, not block render until the fetch finishes. Reach for Suspense only when initial render needs to wait.

About the author

Richard Gamora

Richard Gamora

Fullstack developer based in the Philippines, working mostly with Laravel and Vue.js, with eight years of production experience across web and mobile.

me@richardgamora.comUpwork ↗

More on Vue & Nuxt