Streaming with Suspense lets your app show parts of the page as soon as they are ready. This makes your app feel faster and smoother.
Streaming with Suspense in NextJS
Start learning this pattern below
Jump into concepts and practice - no test required
or
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Introduction
Syntax
NextJS
import { Suspense } from 'react'; export default function Page() { return ( <Suspense fallback={<Loading />}> <SomeComponent /> </Suspense> ); }
The Suspense component wraps parts that may load slowly.
The fallback prop shows a placeholder while loading.
Examples
NextJS
import { Suspense } from 'react'; function Loading() { return <p>Loading...</p>; } function Data() { // Imagine this fetches data return <p>Data loaded!</p>; } export default function Page() { return ( <Suspense fallback={<Loading />}> <Data /> </Suspense> ); }
NextJS
import { Suspense } from 'react'; function Loading() { return <p>Loading user info...</p>; } function UserInfo() { // Simulate slow data return <p>User: Alice</p>; } export default function Profile() { return ( <div> <h1>Profile</h1> <Suspense fallback={<Loading />}> <UserInfo /> </Suspense> </div> ); }
Sample Program
This component shows a blog post with comments. The comments are wrapped in Suspense to show a loading message if they take time to load.
NextJS
import { Suspense } from 'react'; function Loading() { return <p>Loading comments...</p>; } function Comments() { // Simulate slow loading with a delay const comments = ['Great post!', 'Thanks for sharing.', 'Nice article!']; return ( <ul> {comments.map((comment, i) => ( <li key={i}>{comment}</li> ))} </ul> ); } export default function BlogPost() { return ( <article> <h1>My Blog Post</h1> <p>This is the content of the blog post.</p> <Suspense fallback={<Loading />}> <Comments /> </Suspense> </article> ); }
Important Notes
Suspense works best with components that fetch data or load slowly.
Use simple fallback UI to keep users informed during loading.
Streaming with Suspense improves perceived speed by showing content early.
Summary
Streaming with Suspense lets parts of your page load and show separately.
Wrap slow components in Suspense with a fallback UI.
This makes your app feel faster and more responsive.
Practice
1. What is the main purpose of using
Suspense in Next.js streaming?easy
Solution
Step 1: Understand Suspense role
Suspenseis used to wrap components that may take time to load, showing a fallback UI meanwhile.Step 2: Identify the purpose in streaming
In streaming, it helps parts of the page appear quickly by showing placeholders until content is ready.Final Answer:
To show a fallback UI while waiting for slow components to load -> Option AQuick Check:
Suspense fallback = show UI while loading [OK]
Hint: Suspense shows fallback UI during loading [OK]
Common Mistakes:
- Thinking Suspense stops rendering completely
- Confusing Suspense with caching
- Assuming Suspense disables server rendering
2. Which of the following is the correct way to use
Suspense in a Next.js component?easy
Solution
Step 1: Check Suspense syntax
TheSuspensecomponent requires afallbackprop with a React node, and must wrap the child component properly.Step 2: Identify correct JSX structure
<Suspense fallback="Loading..."><MyComponent /></Suspense>correctly usesfallback="Loading..."and properly closes theSuspensetag.Final Answer:
<Suspense fallback="Loading..."><MyComponent /></Suspense> -> Option CQuick Check:
Suspense fallback prop + proper closing = correct syntax [OK]
Hint: Suspense needs fallback prop and closing tag [OK]
Common Mistakes:
- Forgetting to close Suspense tag
- Passing fallback inside child component
- Using fallback as string with JSX tags
3. Given this Next.js component using streaming with Suspense:
What will the user see first when this page loads?
import { Suspense } from 'react';
function SlowComponent() {
return Data loaded;
}
export default function Page() {
return (
Loading...}>
);
}What will the user see first when this page loads?
medium
Solution
Step 1: Check if SlowComponent suspends
SlowComponentis synchronous and returns<div>Data loaded</div>immediately without throwing a promise, so Suspense does not trigger fallback.Step 2: Determine initial render behavior
The entire page renders instantly with 'Data loaded' inside the div. No fallback appears because there is no suspension.Final Answer:
Only 'Data loaded' without any loading text -> Option DQuick Check:
No suspend = no fallback, direct content render [OK]
Hint: Suspense fallback only if children suspend (throw promise) [OK]
Common Mistakes:
- Assuming Suspense always shows fallback
- Thinking synchronous components trigger loading
- Expecting streaming without suspend mechanism
4. Identify the error in this Next.js streaming code snippet:
import { Suspense } from 'react';
export default function Page() {
return (
<div>
<Suspense fallback="Loading...">
<SlowComponent />
</Suspense>
</div>
);
}
function SlowComponent() {
throw new Promise(resolve => setTimeout(resolve, 1000));
return <div>Loaded</div>;
}medium
Solution
Step 1: Spot unreachable code
Thereturn <div>Loaded</div>afterthrowis unreachable because the throw executes first.Step 2: Validate other parts
Import from 'react' is correct; throwing a Promise suspends correctly (though recreating it causes infinite loop here); fallback string is valid ReactNode.Final Answer:
The return statement after throw is unreachable -> Option AQuick Check:
throw before return = unreachable [OK]
Hint: Code after throw is unreachable [OK]
Common Mistakes:
- Thinking fallback string causes issues
- Believing components cannot throw Promises
- Wrong import source for Suspense
5. You want to stream two slow components in Next.js with Suspense, showing their fallbacks independently. Which approach correctly achieves this?
hard
Solution
Step 1: Understand independent Suspense boundaries
Wrapping each slow component in its ownSuspenseallows each to show its own fallback independently.Step 2: Analyze options
<Suspense fallback="Loading A..."><ComponentA /></Suspense><Suspense fallback="Loading B..."><ComponentB /></Suspense>wraps each component separately with distinct fallbacks, enabling independent streaming.<Suspense fallback="Loading A and B..."><ComponentA /><ComponentB /></Suspense>shares one fallback for both, so they load together.<ComponentA /><ComponentB />without Suspense has no fallback.<Suspense fallback="Loading..."><ComponentA /></Suspense><ComponentB fallback="Loading B..." />incorrectly uses fallback on a component.Final Answer:
<Suspense fallback="Loading A..."><ComponentA /></Suspense><Suspense fallback="Loading B..."><ComponentB /></Suspense> -> Option BQuick Check:
Separate Suspense per component = independent fallbacks [OK]
Hint: Wrap each slow component in its own Suspense [OK]
Common Mistakes:
- Using one Suspense for multiple components expecting separate fallbacks
- Not wrapping slow components in Suspense
- Passing fallback prop to child components
