Skip to content

[Nuxt] sentry--nuxt-pages-data template uses addTemplate but is imported from server plugin via #build — breaks on Nuxt 4.4+ #20010

@JoelCode

Description

@JoelCode

Is there an existing issue for this?

How do you use Sentry?

Sentry Saas (sentry.io)

Which SDK are you using?

@sentry/nuxt

SDK Version

10.46.0

Framework Version

Nuxt 4.4.2

Link to Sentry event

No response

Reproduction Example/SDK Setup

Any Nuxt 4.4+ project with @sentry/nuxt configured.

Steps to Reproduce

  1. Create a Nuxt 4.4+ project with @sentry/nuxt/module in modules
  2. Run nuxt build (or deploy to Vercel)
  3. The Nitro Rollup build fails with:
[error] Could not resolve "./_nuxt/virtual_nuxt__vercel_path0_node_modules_.cache_nuxt_.nuxt_sentry--nuxt-pages-data-Baofsjfh.js" from "node_modules/.cache/nuxt/.nuxt/dist/server/server.mjs"

Expected Result

The build should complete successfully. The sentry--nuxt-pages-data template should be available to the server-side route-detector.server.js plugin.

Actual Result

The Nitro Rollup build fails because it cannot resolve the sentry--nuxt-pages-data module from the server bundle.

Root Cause

The Sentry Nuxt module creates the pages data template using addTemplate() (a client/app-side Nuxt utility):

// packages/nuxt/src/module.ts
const pagesDataTemplate = addTemplate({
  filename: "sentry--nuxt-pages-data.mjs",
  getContents: () => "export default [];"
});

Then the server-side route-detector.server.js plugin imports it via the #build alias:

const { default: importedPagesData } = await import("#build/sentry--nuxt-pages-data.mjs");

This violates Nuxt's architecture. Nuxt intentionally blocks #build aliases in server runtime code via the impound plugin (see nuxt/nuxt#29302). The #build directory is for client/app code; server code runs in a separate Nitro build context.

Nuxt maintainer Daniel Roe confirmed this is the wrong approach and pointed to two correct alternatives:

  • addServerTemplate() (available since Nuxt 3.15 / @nuxt/kit, see nuxt/nuxt#29320)
  • nitro.options.virtual for creating virtual modules accessible in the Nitro build

This pattern happened to work on Nuxt <=4.2.x because import protection was less strict and the Rollup resolution path inlined the template. Nuxt 4.4 tightened import protection (PR #34454), migrated to unrouting (PR #34316), and upgraded to Vue Router v5 (PR #34181), which collectively cause the Nitro Rollup build to resolve the #build import to a client-side chunk path that doesn't exist.

Suggested Fix

Replace addTemplate() with addServerTemplate() for the sentry--nuxt-pages-data.mjs file so it's properly available in the Nitro build context.

Workaround

Pin Nuxt to ~4.2.1 in package.json until this is fixed.

Additional Context

The route-detector.server.js plugin already wraps the import in a try/catch, so if addServerTemplate changes the import path, the fallback to an empty array still works. The feature (parametrized route names on server spans) is non-critical.

Tested on Vercel with the node-server Nitro preset. The error also occurs locally on macOS with nuxt build.

Metadata

Metadata

Assignees

No one assigned
    No fields configured for issues without a type.

    Projects

    Status

    Waiting for: Product Owner

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions