static-viewport-dynamic.mdx
title: Next.js encountered uncached data in generateViewport() 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, generateViewport() 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 in generateViewport() on a route that must be fully static.
Ways to fix this
<FixCardGrid> <FixCard group="cache" title="Cache the viewport" href="#cache-the-viewport" snippets={[ { text: 'async function generateViewport() {' }, { text: ' "use cache"', highlight: true }, { text: ' return await cms.getViewport(…)' }, ]} /> <FixCard group="static" title="Use static viewport" href="#use-static-viewport" snippets={[ { text: 'export const viewport = {', highlight: true }, { text: " themeColor: 'black'" }, { text: '}' }, ]} /> </FixCardGrid>Cache the viewport
Choose this fix when viewport data can be shared across requests.
Patterns
Add use cache to generateViewport()
Cache generateViewport() with use cache and choose an appropriate cacheLife profile:
import { cacheLife } from 'next/cache'
export async function generateViewport() {
'use cache'
cacheLife('hours')
const response = await fetch('https://api.example.com/content')
const data = await response.json()
return { themeColor: data.themeColor }
}
Learn more: Caching with use cache.
Trade-off
Visitors share the cached viewport data until it is revalidated.
Gotchas
- This fix does not apply to
connection(), whose purpose is to require request-time rendering. - Caching does not make cookies, headers, parameters, or search parameters static.
Use static viewport
Choose this fix when viewport settings do not need the uncached value.
Patterns
Export a static viewport object
Replace generateViewport() with a static viewport export:
export const viewport = { themeColor: 'black' }
Learn more: Static viewport.
Trade-off
The viewport is determined during prerendering rather than from the removed data source.
Gotchas
- This fixes viewport settings only. Page content, metadata, and other segments must also satisfy the static requirement.
- If the value must be generated for each request, first confirm that request-time rendering is intended for the entire route. See Remove the static requirement.
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 function 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 viewport settings.
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.
Related validation errors
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.