Forcing Dynamic Rendering

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.

4 min read Level 2/5 #nextjs#dynamic#force-dynamic
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.

The Data Cache →