How to Use Suspense in Next.js for Loading States
In Next.js, you use
React.Suspense to wrap components that load asynchronously, showing a fallback UI while waiting. Wrap your lazy-loaded or server components inside <Suspense fallback="..."> to display a loading indicator until the content is ready.Syntax
The Suspense component wraps around any child component that loads asynchronously. It takes a fallback prop which is the UI shown while waiting.
<Suspense fallback="<Loading />">: Wraps the lazy or async component.fallback: A React element shown during loading, like a spinner or text.- Child components: Usually lazy-loaded with
React.lazy()or server components that suspend.
jsx
import React, { Suspense, lazy } from 'react'; const LazyComponent = lazy(() => import('./LazyComponent')); export default function Page() { return ( <Suspense fallback={<div>Loading...</div>}> <LazyComponent /> </Suspense> ); }
Example
This example shows how to use Suspense with a lazy-loaded component in Next.js. While LazyComponent loads, the fallback text "Loading..." appears.
jsx
import React, { Suspense, lazy } from 'react'; const LazyComponent = lazy(() => new Promise(resolve => { setTimeout(() => resolve(import('./LazyComponent')), 2000); })); export default function Home() { return ( <main> <h1>Welcome to Next.js Suspense Demo</h1> <Suspense fallback={<p>Loading component...</p>}> <LazyComponent /> </Suspense> </main> ); } // LazyComponent.js // export default function LazyComponent() { // return <div>This is the lazy loaded component!</div>; // }
Output
<main>
<h1>Welcome to Next.js Suspense Demo</h1>
<p>Loading component...</p> <!-- shown for 2 seconds -->
<div>This is the lazy loaded component!</div> <!-- then appears -->
</main>
Common Pitfalls
- Not wrapping lazy components inside
Suspensecauses errors. - Using Suspense on server components without proper support may not work as expected.
- Fallback UI should be simple and fast to render to avoid blocking.
- For Next.js 13+, use
Suspensewith client components only.
jsx
/* Wrong: Lazy component without Suspense */ import React, { lazy } from 'react'; const LazyComp = lazy(() => import('./LazyComp')); export default function Page() { return <LazyComp />; // This will throw an error } /* Right: Wrap with Suspense */ import React, { Suspense, lazy } from 'react'; const LazyComp = lazy(() => import('./LazyComp')); export default function Page() { return ( <Suspense fallback={<div>Loading...</div>}> <LazyComp /> </Suspense> ); }
Quick Reference
- Wrap async components: Always use
<Suspense fallback="...">around lazy or async components. - Fallback UI: Use simple loading indicators like text or spinners.
- Next.js 13+: Use Suspense only in client components, not server components.
- Lazy loading: Use
React.lazy()for dynamic imports.
Key Takeaways
Always wrap lazy or async components in
Suspense with a fallback UI.Use simple and fast fallback content to keep the UI responsive during loading.
In Next.js 13 and later, use Suspense only inside client components.
Not using Suspense around lazy components causes runtime errors.
React.lazy() works well with Suspense for dynamic imports in Next.js.