Getting Started

Limitations

Limitations

TL;DR

  • nuxt dev won't catch misuse. The transform plugin is skipped in dev mode, so usePrerenderData handlers always run.
  • Incorrect usage only surfaces at runtime in production, not at build time. For example, if usePrerenderData is used on a non-prerendered page, the build succeeds — the error is thrown when the page is actually requested.
  • nuxt generate is always safe. Every route is prerendered, so handlers always execute correctly.
  • nuxt build with SSR fallback will show a Nuxt error page if a non-prerendered page uses usePrerenderData. The error is caught by useAsyncData and 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 generate for full SSG — no risk of misuse.
  • If using nuxt build with selective prerendering, ensure all pages using usePrerenderData are 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:

  1. Client bundles: import.meta.prerender is statically false at compile time, so bundlers eliminate the handler via dead code elimination (DCE) — server code never appears in the client bundle.
  2. Server bundles: import.meta.prerender is a runtime value — true during prerendering, false during 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: neverReachable throws — 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

ContextPlugin transforms?import.meta.prerenderHandler runs?Error?
nuxt devNoN/AYes (directly)No error — always works in dev
nuxt generate (prerender)YestrueYesNo error — correct usage
nuxt build (prerender phase)YestrueYesNo error — correct usage
nuxt build (SSR fallback)YesfalseNoRuntime error with helpful message
Client bundleYesfalse (static)NoN/A — server code fully removed
Copyright © 2026