Limitations
Limitations
TL;DR
nuxt devwon't catch misuse. The transform plugin is skipped in dev mode, sousePrerenderDatahandlers always run.- Incorrect usage only surfaces at runtime in production, not at build time. For example, if
usePrerenderDatais used on a non-prerendered page, the build succeeds — the error is thrown when the page is actually requested. nuxt generateis always safe. Every route is prerendered, so handlers always execute correctly.nuxt buildwith SSR fallback will show a Nuxt error page if a non-prerendered page usesusePrerenderData. The error is caught byuseAsyncDataand surfaced as a fatal error — the build itself succeeds, the error occurs when the page is requested.- No server code or data ever leaks to the client, even on misuse. The client bundle eliminates handlers via dead code elimination. The server bundle throws before any data is fetched.
Recommendation
- Use
nuxt generatefor full SSG — no risk of misuse. - If using
nuxt buildwith selective prerendering, ensure all pages usingusePrerenderDataare in the prerender routes list.
How the transform plugin works
nuxt-prerender-kit includes a Vite transform plugin that wraps usePrerenderData handlers with a conditional:
import.meta.prerender ? handler : __neverReachable_prerender()
This serves two purposes:
- Client bundles:
import.meta.prerenderis staticallyfalseat compile time, so bundlers eliminate the handler via dead code elimination (DCE) — server code never appears in the client bundle. - Server bundles:
import.meta.prerenderis a runtime value —trueduring prerendering,falseduring SSR — so the handler only executes when generating static pages.
Dev mode: no transformation
In dev mode (nuxt dev), Nuxt serves all pages via SSR — there is no prerender phase. The plugin detects dev mode and skips transformation entirely, so handlers run directly through useAsyncData.
usePrerenderData() called
→ No transformation applied (plugin skips in dev)
→ Handler runs directly via useAsyncData
→ Data served to page ✅
This means everything works in dev, but misuse of usePrerenderData on a non-SSG page won't surface until production build.
Production: nuxt generate
During nuxt generate, every route is prerendered. The plugin wraps handlers, and import.meta.prerender is true for all routes.
usePrerenderData() called
→ Plugin wraps handler with import.meta.prerender conditional
→ import.meta.prerender = true
→ Handler executes
→ Data serialized into HTML ✅
This is the intended and safest usage — no risk of misuse.
Production: nuxt build with SSR fallback
If usePrerenderData is used on a page that isn't in the prerender routes list, the handler is wrapped but import.meta.prerender is false at runtime. The neverReachable function throws a descriptive error directing users to use useAsyncData instead.
usePrerenderData() called
→ Plugin wraps handler with import.meta.prerender conditional
→ import.meta.prerender = false
→ neverReachable throws ❌
→ Runtime error with descriptive message
The error is caught at runtime (when the page is requested), not at build time — the build itself succeeds because import.meta.prerender is a runtime value in the server bundle.
Client bundle: server code fully removed
In the client bundle, import.meta.prerender is statically false at compile time. The bundler's dead code elimination removes the handler entirely — server code is never included.
usePrerenderData() called
→ Plugin wraps handler with import.meta.prerender conditional
→ import.meta.prerender = false (static, at compile time)
→ Dead Code Elimination removes handler entirely
→ Server code not in client bundle ✅
Even when usePrerenderData is incorrectly used in an SSR context, no server code or data leaks to the client. The client and server bundles are built independently:
- Client bundle: DCE removes the handler entirely — server code is never included.
- Server bundle:
neverReachablethrows — the handler never executes, no data is fetched or returned.
The worst case is a runtime error on the server — never a security or data exposure issue.
Behavior matrix
| Context | Plugin transforms? | import.meta.prerender | Handler runs? | Error? |
|---|---|---|---|---|
nuxt dev | No | N/A | Yes (directly) | No error — always works in dev |
nuxt generate (prerender) | Yes | true | Yes | No error — correct usage |
nuxt build (prerender phase) | Yes | true | Yes | No error — correct usage |
nuxt build (SSR fallback) | Yes | false | No | Runtime error with helpful message |
| Client bundle | Yes | false (static) | No | N/A — server code fully removed |