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 withuse(including data streamed from Server Components or loaded through a Suspense-enabled framework), stylesheets withprecedence, and streaming server HTML. It does not detect fetching insideuseEffector 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>Related
- code-splitting:
lazyneeds a boundary. - hydration: boundaries hydrate independently.
- server-component: async Server Components stream through boundaries.
- react-suspense: patterns in depth.
- react: the rendering model.
- nextjs: streaming in the App Router.