export const dynamic = 'force-dynamic'
Forcing Dynamic Rendering
When in doubt, opt a route into dynamic rendering explicitly so its behaviour does not depend on whether someone added a cached fetch.
What you'll learn
- Use `export const dynamic = 'force-dynamic'`
- Use `unstable_noStore()` to opt out of caching for one fetch
- Combine with streaming for a fast TTFB
Sometimes you want a route to be dynamic without depending on what its child components
happen to do. The route segment config option dynamic makes the choice explicit.
force-dynamic
// app/feed/page.tsx
export const dynamic = 'force-dynamic'
export default async function Page() {
// Always SSR. Adding a cached fetch will not change that.
} This is useful for live feeds, dashboards, and anything where freshness is non-negotiable.
Per-call Opt-out with unstable_noStore
import { unstable_noStore as noStore } from 'next/cache'
export default async function Page() {
noStore()
const data = await fetch('https://api.example.com/live').then((r) => r.json())
return <Live data={data} />
} noStore() tells Next that the surrounding render must not be cached, without
needing to touch every fetch call individually.
Streaming for Fast TTFB
Forcing dynamic rendering does not mean a slow first byte. Wrap the slow part in
<Suspense> and the static shell flushes immediately:
import { Suspense } from 'react'
export const dynamic = 'force-dynamic'
export default function Page() {
return (
<main>
<h1>Feed</h1>
<Suspense fallback={<p>Loading…</p>}>
<FeedList />
</Suspense>
</main>
)
} The header renders instantly; FeedList streams in when its data resolves.