static-route-dynamic.mdx


title: Next.js encountered uncached data on a route that must be fully static kind: error

<div style={{ padding: '1.25rem 1.5rem', border: '1px solid var(--ds-gray-400)', borderRadius: '12px', background: 'var(--ds-background-200)', margin: '1.5rem 0 2rem', fontSize: '0.95rem', lineHeight: '1.6', }} > This error is part of the [Instant Navigations](https://nextjs.org/blog/next-16-3-instant-navigations) feature introduced in Next.js 16.3. If you're new to it, start with the [Ensuring instant navigations](/docs/app/guides/instant-navigation) guide. </div>

A page or layout on this route exports ensureStatic with the 'navigation' value, requiring all server-rendered work for the route to complete during prerendering.

During prerendering, the page or layout performed an uncached fetch() request, database call, or connection(). The operation requires rendering at request time, which conflicts with the route's static requirement.

During next build, Next.js may link to this page when it cannot distinguish uncached data from runtime data. For a short cache, extend the cache lifetime.

Request-specific reads from cookies(), headers(), params, or searchParams have different fixes. See Runtime data on a route that must be fully static.

Ways to fix this

<FixCardGrid> <FixCard group="cache" title="Cache the data" href="#cache-the-data" snippets={[ { text: 'async function getData() {' }, { text: ' "use cache"', highlight: true }, { text: ' return await db.query(…)' }, ]} /> <FixCard group="remove" title="Remove the data access" href="#remove-the-data-access" snippets={[ { text: 'async function Page() {' }, { text: '- await connection()', highlight: true }, { text: ' return <Content />' }, ]} /> <FixCard group="client" title="Read the data on the client" href="#read-the-data-on-the-client" snippets={[ { text: "'use client'" }, { text: "const { data } = useSWR('/api', fetcher)", highlight: true, }, { text: 'return <Content data={data} />' }, ]} /> </FixCardGrid>

Cache the data

Choose this fix when the data can be shared across requests.

Patterns

Add use cache to the data access

Cache the asynchronous function with use cache and choose an appropriate cacheLife profile:

import { cacheLife } from 'next/cache'

export default async function Page() {
  'use cache'
  cacheLife('hours')
  const response = await fetch('https://api.example.com/content')
  const data = await response.json()
  return <h1>{data.title}</h1>
}

Learn more: Caching with use cache.

Trade-off

Visitors share the cached result until it is revalidated.

Gotchas

  • This fix does not apply to connection(), whose purpose is to require request-time rendering.
  • Caching does not make request-specific cookies, headers, parameters, or search parameters static.

Remove the data access

Choose this fix when the operation is unnecessary.

Patterns

Remove the uncached operation

Remove the access rather than only removing the JSX that displays its result:

export const ensureStatic = 'navigation'

export default function Page() {
  return <h1>My page</h1>
}

Trade-off

Every visitor receives the same output because the removed operation no longer runs per request.

Gotchas

  • Other uncached or runtime data in the route, including layouts and metadata, must also be resolved.
  • If the operation must run for each request, first confirm that request-time rendering is intended for the entire route. See Remove the static requirement.

Read the data on the client

Choose this fix when the data can load in the browser after the static output renders.

Patterns

Fetch in a Client Component

Move the request to a Client Component. A client data-fetching library can provide loading states, caching, and revalidation in the browser:

'use client'

import useSWR from 'swr'

const fetcher = (url: string) => fetch(url).then((response) => response.json())

export default function Recommendations() {
  const { data, error, isLoading } = useSWR('/api/recommendations', fetcher)

  if (error) return <p>Failed to load recommendations.</p>
  if (isLoading) return <p>Loading recommendations...</p>

  return <p>{data.summary}</p>
}

Learn more: Client-side data fetching.

Trade-off

The prerender does not include this data, and the browser makes an additional request after hydration.

Gotchas

  • Protect the API endpoint with the same authorization checks as the original server-side data access.
  • This pattern adds a client-side request. Prefer caching the server data when visitors can share the result.

Verifying the fix

After applying a fix, rerun next build and confirm that the route completes prerendering. If the error also appeared in next dev, reload the route and confirm that the overlay clears. Wrapping the operation in Suspense or setting instant = false does not relax this static requirement.

In next dev, the error overlay points at the failing component with file paths and line numbers. Run next build --debug-prerender for full user-frame stack traces and next build --debug-build-paths /dashboard /settings to iterate on specific routes.

Remove the static requirement

The 'navigation' value is usually set deliberately to guarantee static output for the entire server-rendered route. Removing it relaxes that requirement for every segment, not only the code that triggered this error.

If request-time rendering is intentional for this route, remove ensureStatic = 'navigation' from every page or layout that sets it. The route then follows the ordinary Cache Components rendering rules.

Learn more: Combining ensureStatic levels across layouts and pages.

See Instant Navigation validation errors for the complete reference.

Rendered from the public repository vercel/next.js on GitHub; content belongs to its authors. Cached for up to an hour.

errors/static-route-dynamic.mdx · vercel/next.js | Docs MD