Overview

<Suspense fallback={...}> shows its fallback while a child is not ready and reveals the content when it is. Where you place boundaries decides which parts of a page stream in first and which wait together: wrap slow, independent sections separately instead of the whole route.

Rules

  • Suspense activates for lazy components (lazy), promises read with use (including data streamed from Server Components or loaded through a Suspense-enabled framework), stylesheets with precedence, and streaming server HTML. It does not detect fetching inside useEffect or event handlers.
  • Wrap every React.lazy() component in a boundary. In the Next.js App Router, boundaries are the streaming units, so place them around slow data. Avoid a single root boundary.
  • On the server, React sends the fallback in the initial HTML and streams the real content as it resolves. On the client, each boundary hydrates independently (selective hydration).
  • Suspense handles loading only; failures need an error boundary (react-error-boundaries).
const HeavyChart = lazy(() => import("./HeavyChart"))
 
<Suspense fallback={<ChartSkeleton />}>
  <HeavyChart />
</Suspense>