0
0
NextjsHow-ToIntermediate · 4 min read

How to Use Suspense for Streaming in Next.js

In Next.js, you can use React.Suspense to wrap components that load asynchronously, enabling streaming of server-rendered content. Wrap your async component inside <Suspense fallback="..."> to show a placeholder while loading, and Next.js will stream the content as it becomes ready.
📐

Syntax

Use React.Suspense to wrap components that load data or code asynchronously. The fallback prop defines what to show while waiting. Inside Next.js, this enables streaming parts of the UI as they load.

  • <Suspense fallback="Loading...">: Shows fallback UI while waiting.
  • <AsyncComponent />: The component that loads asynchronously.
  • </Suspense>: Ends the Suspense wrapper.
jsx
import React, { Suspense } from 'react';

function AsyncComponent() {
  // Async logic or data fetching here
  return <div>Async content loaded</div>;
}

export default function Page() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <AsyncComponent />
    </Suspense>
  );
}
Output
<div>Loading...</div> (initially), then <div>Async content loaded</div> when ready
💻

Example

This example shows a Next.js page streaming a component that simulates a delay using setTimeout. The Suspense fallback displays a loading message until the content is ready.

jsx
import React, { Suspense, useState, useEffect } from 'react';

function DelayedContent() {
  const [ready, setReady] = useState(false);

  useEffect(() => {
    const timer = setTimeout(() => setReady(true), 2000); // 2 seconds delay
    return () => clearTimeout(timer);
  }, []);

  if (!ready) {
    throw new Promise(() => {}); // Suspend until ready
  }

  return <div>Content loaded after delay!</div>;
}

export default function Page() {
  return (
    <main>
      <h1>Streaming with Suspense in Next.js</h1>
      <Suspense fallback={<div>Loading delayed content...</div>}>
        <DelayedContent />
      </Suspense>
    </main>
  );
}
Output
<h1>Streaming with Suspense in Next.js</h1> <div>Loading delayed content...</div> (for 2 seconds), then <div>Content loaded after delay!</div>
⚠️

Common Pitfalls

Common mistakes when using Suspense for streaming in Next.js include:

  • Not throwing a Promise inside the async component to trigger Suspense.
  • Using Suspense on the client side only without server support, which disables streaming.
  • Forgetting to provide a fallback UI, causing blank screens during loading.
  • Trying to use Suspense with data fetching methods that do not support React's Suspense mechanism.

Always ensure your async components throw a Promise to suspend rendering and that your Next.js version supports streaming with Suspense.

jsx
import React, { Suspense } from 'react';

// Wrong: async component returns null instead of suspending
function WrongAsync() {
  // This will not suspend rendering
  return null;
}

// Right: async component throws a Promise to suspend
function RightAsync() {
  throw new Promise(resolve => setTimeout(resolve, 1000));
  // After 1 second, component will render
  // Note: code after throw is unreachable
}

export default function Page() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      {/* WrongAsync will not trigger Suspense fallback */}
      {/* <WrongAsync /> */}

      {/* RightAsync will trigger Suspense fallback */}
      <RightAsync />
    </Suspense>
  );
}
Output
<div>Loading...</div> (for 1 second), then <div>Loaded!</div>
📊

Quick Reference

ConceptDescription
Wraps async components and shows fallback UI while loading
Throwing a PromiseAsync components must throw a Promise to suspend rendering
StreamingNext.js streams content as async components resolve inside Suspense
Fallback UIPlaceholder UI shown until async content is ready
Server SupportStreaming with Suspense requires Next.js server components and React 18+

Key Takeaways

Wrap async components in with a fallback to enable streaming in Next.js.
Async components must throw a Promise to suspend rendering and trigger Suspense.
Always provide a fallback UI to avoid blank screens during loading.
Streaming with Suspense requires React 18+ and Next.js server components support.
Test your Suspense components to ensure they properly suspend and resume rendering.