Loading UI & Streaming with Suspense
5 questions found
How do you show a loading state automatically while a page's data is being fetched in the App Router?
Beginner
You add a file named loading.js inside the same route folder as your page, and Next.js automatically displays it while the page's server component is fetching data, giving users instant visual feedback instead of a blank screen while they wait.
// app/dashboard/loading.js
export default function Loading() {
return <p>Loading dashboard...</p>;
}
Real-world example
A dashboard shows a friendly loading spinner immediately while it fetches the user's data in the background, giving instant feedback instead of leaving the screen blank.
Common follow-ups: How does loading.js relate to React Suspense under the hood?;Can you customize the loading indicator with a skeleton screen instead of plain text?
Data Fetching;Rendering (SSR/SSG/ISR)
What is streaming in Next.js, and how does it improve the user experience?
Intermediate
Streaming lets Next.js send parts of a page to the browser as soon as they are ready, instead of waiting for every piece of data on the page to finish loading first. This means fast parts of a page, like the header, can appear immediately, while slower parts load in and appear a moment later.
// app/page.js
import { Suspense } from 'react';
export default function Page() {
return (
<div>
<Header />
<Suspense fallback={<p>Loading comments...</p>}>
<Comments />
</Suspense>
</div>
);
}
Real-world example
A news article page shows the article text immediately while a slower loading comments section streams in a moment later, so readers are not stuck waiting for the entire page before seeing anything.
Common follow-ups: What happens if a streamed component's data fetch fails?;Can multiple Suspense boundaries be used on the same page?
Data Fetching;Web Vitals & Performance Monitoring
How do you use multiple Suspense boundaries on the same page to stream different sections independently?
Intermediate
You wrap each slow loading section of your page in its own Suspense component with a specific fallback, letting each section stream in independently as soon as its own data is ready, rather than having one slow piece of data delay the appearance of everything else on the page.
<div>
<Suspense fallback={<Skeleton />}>
<UserProfile />
</Suspense>
<Suspense fallback={<Skeleton />}>
<RecentOrders />
</Suspense>
</div>
Real-world example
An account page shows the user's profile information as soon as it loads, while their recent orders section, which takes longer to fetch, streams in separately without blocking the profile from appearing first.
Common follow-ups: Does the order of Suspense boundaries in the code affect the order they stream in?;How do you decide where to place Suspense boundaries for the best experience?
Data Fetching;Performance & Lazy Loading
How does streaming interact with search engines and SEO, since content is sent in pieces rather than all at once?
Advanced
Search engine crawlers typically wait for the full page to finish rendering before indexing it, so streaming does not usually harm SEO for content that is important for search rankings, but it is still best practice to ensure your most important content, like headings and main text, appears in the earliest streamed part of the page.
// Ensure critical SEO content loads early
export default function Page() {
return (
<div>
<h1>Article Title</h1>
<Suspense fallback={<p>Loading related articles...</p>}>
<RelatedArticles />
</Suspense>
</div>
);
}
Real-world example
A blog places its article title and main content outside any Suspense boundary so it streams first, while less important related article suggestions stream in afterward without affecting how search engines see the page.
Common follow-ups: Do all search engines handle streamed content the same way?;Should the most SEO critical content always avoid being wrapped in Suspense?
Metadata API & SEO Optimization;Rendering (SSR/SSG/ISR)
How would you design loading states for a complex page with several independently loading sections to avoid a jarring, jumpy user experience?
Advanced
You design skeleton loading placeholders that closely match the actual size and shape of the content that will eventually appear, use consistent Suspense boundaries so sections load in a predictable order, and avoid excessive layout shift by reserving the correct amount of space for each section before its real content arrives.
function CardSkeleton() {
return <div className="h-32 w-full animate-pulse bg-gray-200 rounded" />;
}
<Suspense fallback={<CardSkeleton />}>
<ProductCard />
</Suspense>
Real-world example
A product listing page uses skeleton cards that match the exact size of the real product cards, so the page layout does not jump around awkwardly as real content streams in and replaces the placeholders.
Common follow-ups: What tools help measure layout shift caused by streaming content?;How do you test that skeleton screens closely match final content sizes?
Web Vitals & Performance Monitoring;Rendering (SSR/SSG/ISR)