File: nextjs-suspense-streaming.md | Updated: 11/15/2025
Search...
+ K
Auto
Docs Examples GitHub Contributors
Docs Examples GitHub Contributors
Docs Examples GitHub Contributors
Docs Examples Github Contributors
Docs Examples Github Contributors
Docs Examples Github Contributors
Docs Examples Github Contributors
Docs Examples Github Contributors
Maintainers Partners Support Learn StatsBETA Discord Merch Blog GitHub Ethos Brand Guide
Documentation
Framework
React
Version
Latest
Search...
+ K
Menu
Getting Started
Guides & Concepts
API Reference
ESLint
Examples
Plugins
Framework
React
Version
Latest
Menu
Getting Started
Guides & Concepts
API Reference
ESLint
Examples
Plugins
React Example: Nextjs Suspense Streaming
=============================================================================================================================================================================================================================================================================================================================================================================================================================================================================
Code ExplorerCode
Interactive SandboxSandbox
src
app
api
layout.tsx
page.tsx
providers.tsx
.gitignore
next.config.js
package.json
tsconfig.json
tsx
'use client'
import { isServer, useSuspenseQuery } from '@tanstack/react-query'
import { Suspense } from 'react'
export const runtime = 'edge' // 'nodejs' (default) | 'edge'
function getBaseURL() {
if (!isServer) {
return ''
}
if (process.env.VERCEL_URL) {
return `https://${process.env.VERCEL_URL}`
}
return 'http://localhost:3000'
}
const baseUrl = getBaseURL()
function useWaitQuery(props: { wait: number }) {
const query = useSuspenseQuery({
queryKey: ['wait', props.wait],
queryFn: async () => {
const path = `/api/wait?wait=${props.wait}`
const url = baseUrl + path
const res: string = await (
await fetch(url, {
cache: 'no-store',
})
).json()
return res
},
})
return [query.data as string, query] as const
}
function MyComponent(props: { wait: number }) {
const [data] = useWaitQuery(props)
return <div>result: {data}</div>
}
export default function MyPage() {
return (
<>
<Suspense fallback={<div>waiting 100....</div>}>
<MyComponent wait={100} />
</Suspense>
<Suspense fallback={<div>waiting 200....</div>}>
<MyComponent wait={200} />
</Suspense>
<Suspense fallback={<div>waiting 300....</div>}>
<MyComponent wait={300} />
</Suspense>
<Suspense fallback={<div>waiting 400....</div>}>
<MyComponent wait={400} />
</Suspense>
<Suspense fallback={<div>waiting 500....</div>}>
<MyComponent wait={500} />
</Suspense>
<Suspense fallback={<div>waiting 600....</div>}>
<MyComponent wait={600} />
</Suspense>
<Suspense fallback={<div>waiting 700....</div>}>
<MyComponent wait={700} />
</Suspense>
<fieldset>
<legend>
combined <code>Suspense</code>-container
</legend>
<Suspense
fallback={
<>
<div>waiting 800....</div>
<div>waiting 900....</div>
<div>waiting 1000....</div>
</>
}
>
<MyComponent wait={800} />
<MyComponent wait={900} />
<MyComponent wait={1000} />
</Suspense>
</fieldset>
</>
)
}
'use client'
import { isServer, useSuspenseQuery } from '@tanstack/react-query'
import { Suspense } from 'react'
export const runtime = 'edge' // 'nodejs' (default) | 'edge'
function getBaseURL() {
if (!isServer) {
return ''
}
if (process.env.VERCEL_URL) {
return `https://${process.env.VERCEL_URL}`
}
return 'http://localhost:3000'
}
const baseUrl = getBaseURL()
function useWaitQuery(props: { wait: number }) {
const query = useSuspenseQuery({
queryKey: ['wait', props.wait],
queryFn: async () => {
const path = `/api/wait?wait=${props.wait}`
const url = baseUrl + path
const res: string = await (
await fetch(url, {
cache: 'no-store',
})
).json()
return res
},
})
return [query.data as string, query] as const
}
function MyComponent(props: { wait: number }) {
const [data] = useWaitQuery(props)
return <div>result: {data}</div>
}
export default function MyPage() {
return (
<>
<Suspense fallback={<div>waiting 100....</div>}>
<MyComponent wait={100} />
</Suspense>
<Suspense fallback={<div>waiting 200....</div>}>
<MyComponent wait={200} />
</Suspense>
<Suspense fallback={<div>waiting 300....</div>}>
<MyComponent wait={300} />
</Suspense>
<Suspense fallback={<div>waiting 400....</div>}>
<MyComponent wait={400} />
</Suspense>
<Suspense fallback={<div>waiting 500....</div>}>
<MyComponent wait={500} />
</Suspense>
<Suspense fallback={<div>waiting 600....</div>}>
<MyComponent wait={600} />
</Suspense>
<Suspense fallback={<div>waiting 700....</div>}>
<MyComponent wait={700} />
</Suspense>
<fieldset>
<legend>
combined <code>Suspense</code>-container
</legend>
<Suspense
fallback={
<>
<div>waiting 800....</div>
<div>waiting 900....</div>
<div>waiting 1000....</div>
</>
}
>
<MyComponent wait={800} />
<MyComponent wait={900} />
<MyComponent wait={1000} />
</Suspense>
</fieldset>
</>
)
}
[###### Want to Skip the Docs?
Query.gg - The Official React Query Course
\
“If you’re serious about *really* understanding React Query, there’s no better way than with query.gg”—Tanner Linsley
Learn More](https://query.gg/?s=tanstack)
