Ever clicked a link and sat staring at a blank screen while the page loaded? Streaming is how you stop that from happening.
In the App Router, Next.js lets you progressively stream HTML from the server, so parts of your page can render and appear as soon as they’re ready. Combined with React’s Suspense, this gives you fine-grained control over what loads when, and what the user sees along the way.
In this chapter, you’ll learn how to use streaming and Suspense to improve your app’s perceived performance and user experience.
Why Streaming Matters in Next.js
In the App Router (app/
directory), Next.js supports React’s streaming architecture out of the box.
This means:
- The server can start sending HTML chunks as they’re ready
- Users see content sooner, no need to wait for the full page render
- Loading UI and Suspense boundaries make this feel seamless
How Does It Work?
- Layouts can stream in parallel with page content
<Suspense>
controls where and how loading states appear- Server Components are streamed natively

Streaming Example in Layouts
Structure
app/ layout.tsx page.tsx components/ Sidebar.tsx Feed.tsx
layout.tsx
import { Suspense } from 'react'; import Sidebar from './components/Sidebar'; export default function RootLayout({ children }) { return ( <html> <body> <Suspense fallback={<p>Loading sidebar...</p>}> <Sidebar /> </Suspense> <main>{children}</main> </body> </html> ); }
Sidebar.tsx
// Server Component — runs on the server, no 'use client' needed export default async function Sidebar() { const categories = await fetchCategories(); return ( <aside> {categories.map((cat) => ( <div key={cat.id}>{cat.name}</div> ))} </aside> ); }
While Sidebar
is loading, the fallback UI (Loading sidebar...
) is shown.
The rest of the page (children
) can render in parallel.
Suspense in Page Components
You can also use Suspense inside a page:
import { Suspense } from 'react'; import Feed from './components/Feed'; export default function HomePage() { return ( <> <h1>Home</h1> <Suspense fallback={<p>Loading feed...</p>}> <Feed /> </Suspense> </> ); }
Rules & Best Practices
DO | DON’T |
---|---|
Use Suspense for non-blocking content | Wrap entire page in Suspense (unless intentional) |
Use lightweight fallback UIs | Rely on JS-heavy spinners — keep it fast |
Test loading priority carefully | Assume everything will stream perfectly — test on slow networks |
Benefits of Streaming
- Faster First Contentful Paint (FCP)
- Better user-perceived performance
- Progressive rendering of large pages
- Improves SEO (HTML sent progressively)
Closing Thought
Streaming and Suspense aren’t just nice-to-haves: they change how your app feels to users. Pages appear faster, transitions feel smoother, and large content loads gracefully without blocking the whole experience.
And the best part? With React Server Components and the Next.js App Router, streaming is built-in and no extra plugins or magic required. You just need to use it well.
Next up: How to Handle Authentication & Protected Routes in the Next.js App Router
In the next chapter, we’ll tackle a core challenge for any real-world app: authentication and protected routes. We’ll cover modern patterns that fit beautifully with the App Router and React Server Components. See you there!