From 9929a2a01b1be176cf6cf476e33a4be4a4462720 Mon Sep 17 00:00:00 2001 From: s1gr1d <32902192+s1gr1d@users.noreply.github.com> Date: Mon, 7 Sep 2026 11:40:44 +0200 Subject: [PATCH 1/3] fix(nuxt): Inject handler import from resolved path, delete `addMiddlewareImports()` --- packages/nuxt/src/module.ts | 4 +--- packages/nuxt/src/vite/middlewareConfig.ts | 24 ++++++++-------------- 2 files changed, 9 insertions(+), 19 deletions(-) diff --git a/packages/nuxt/src/module.ts b/packages/nuxt/src/module.ts index 646347db1cee..7ce4020c27fa 100644 --- a/packages/nuxt/src/module.ts +++ b/packages/nuxt/src/module.ts @@ -21,7 +21,7 @@ import { DEV_SERVER_CONFIG_PATH, } from './vite/addServerConfig'; import { addDatabaseInstrumentation } from './vite/databaseConfig'; -import { addMiddlewareImports, addMiddlewareInstrumentation } from './vite/middlewareConfig'; +import { addMiddlewareInstrumentation } from './vite/middlewareConfig'; import { setupOrchestrion } from './vite/orchestrion'; import { setupSourceMaps } from './vite/sourceMaps'; import { addStorageInstrumentation } from './vite/storageConfig'; @@ -120,8 +120,6 @@ export default defineNuxtModule({ addPlugin({ src: moduleDirResolver.resolve('./runtime/plugins/route-detector-legacy.server'), mode: 'server' }); } - // Preps the middleware instrumentation module. - addMiddlewareImports(); addStorageInstrumentation(nuxt, !isNitroV3); addDatabaseInstrumentation(nuxt.options.nitro, !isNitroV3, moduleOptions); diff --git a/packages/nuxt/src/vite/middlewareConfig.ts b/packages/nuxt/src/vite/middlewareConfig.ts index aa8f5a41ea23..007f4d743889 100644 --- a/packages/nuxt/src/vite/middlewareConfig.ts +++ b/packages/nuxt/src/vite/middlewareConfig.ts @@ -1,20 +1,8 @@ -import { addServerImports, createResolver } from '@nuxt/kit'; +import { createResolver } from '@nuxt/kit'; import type { Nitro } from 'nitropack/types'; import * as path from 'path'; import type { InputPluginOption } from 'rollup'; -/** - * Adds a server import for the middleware instrumentation. - */ -export function addMiddlewareImports(): void { - addServerImports([ - { - name: 'wrapMiddlewareHandlerWithSentry', - from: createResolver(import.meta.url).resolve('./runtime/hooks/wrapMiddlewareHandler'), - }, - ]); -} - /** * Adds middleware instrumentation to the Nitro build. * @@ -42,6 +30,9 @@ export function addMiddlewareInstrumentation(nitro: Nitro): void { */ function middlewareInstrumentationPlugin(nitro: Nitro): InputPluginOption { const middlewareFiles = new Set(); + // Imported by absolute path rather than through `#imports`: with `imports.autoImport: false`, + // Nuxt 5 generates an empty server `#imports` module, dropping `addServerImports` registrations. + const wrapperModule = createResolver(import.meta.url).resolve('./runtime/hooks/wrapMiddlewareHandler'); return { name: 'sentry-nuxt-middleware-instrumentation', @@ -58,7 +49,7 @@ function middlewareInstrumentationPlugin(nitro: Nitro): InputPluginOption { if (middlewareFiles.has(id)) { const fileName = path.basename(id); return { - code: wrapMiddlewareCode(code, fileName), + code: wrapMiddlewareCode(code, fileName, wrapperModule), map: null, }; } @@ -72,15 +63,16 @@ function middlewareInstrumentationPlugin(nitro: Nitro): InputPluginOption { * * @param originalCode The original user code of the middleware. * @param fileName The name of the middleware file, used for the span name and logging. + * @param wrapperModule Absolute path of the module exporting `wrapMiddlewareHandlerWithSentry`. * * @returns The wrapped user code of the middleware. */ -function wrapMiddlewareCode(originalCode: string, fileName: string): string { +function wrapMiddlewareCode(originalCode: string, fileName: string, wrapperModule: string): string { // Remove common file extensions const cleanFileName = fileName.replace(/\.(ts|js|mjs|mts|cts)$/, ''); return ` -import { wrapMiddlewareHandlerWithSentry } from '#imports'; +import { wrapMiddlewareHandlerWithSentry } from ${JSON.stringify(wrapperModule)}; function defineInstrumentedEventHandler(handlerOrObject) { return defineEventHandler(wrapMiddlewareHandlerWithSentry(handlerOrObject, '${cleanFileName}')); From 28bb27238eec4f03565e8e90e225d43a2d6986f7 Mon Sep 17 00:00:00 2001 From: s1gr1d <32902192+s1gr1d@users.noreply.github.com> Date: Tue, 8 Sep 2026 13:19:00 +0200 Subject: [PATCH 2/3] import from #imports/server --- packages/nuxt/src/module.ts | 6 +++-- packages/nuxt/src/vite/middlewareConfig.ts | 30 +++++++++++++++------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/packages/nuxt/src/module.ts b/packages/nuxt/src/module.ts index 7ce4020c27fa..34f23a09b4ea 100644 --- a/packages/nuxt/src/module.ts +++ b/packages/nuxt/src/module.ts @@ -21,7 +21,7 @@ import { DEV_SERVER_CONFIG_PATH, } from './vite/addServerConfig'; import { addDatabaseInstrumentation } from './vite/databaseConfig'; -import { addMiddlewareInstrumentation } from './vite/middlewareConfig'; +import { addMiddlewareImports, addMiddlewareInstrumentation } from './vite/middlewareConfig'; import { setupOrchestrion } from './vite/orchestrion'; import { setupSourceMaps } from './vite/sourceMaps'; import { addStorageInstrumentation } from './vite/storageConfig'; @@ -120,6 +120,8 @@ export default defineNuxtModule({ addPlugin({ src: moduleDirResolver.resolve('./runtime/plugins/route-detector-legacy.server'), mode: 'server' }); } + // Preps the middleware instrumentation module. + addMiddlewareImports(); addStorageInstrumentation(nuxt, !isNitroV3); addDatabaseInstrumentation(nuxt.options.nitro, !isNitroV3, moduleOptions); @@ -190,7 +192,7 @@ export default defineNuxtModule({ } if (serverConfigFile) { - addMiddlewareInstrumentation(nitro); + addMiddlewareInstrumentation(nitro, isNitroV3); consoleSandbox(() => { const serverDir = nitro.options.output.serverDir; diff --git a/packages/nuxt/src/vite/middlewareConfig.ts b/packages/nuxt/src/vite/middlewareConfig.ts index 007f4d743889..f761c2b1dbff 100644 --- a/packages/nuxt/src/vite/middlewareConfig.ts +++ b/packages/nuxt/src/vite/middlewareConfig.ts @@ -1,14 +1,27 @@ -import { createResolver } from '@nuxt/kit'; +import { addServerImports, createResolver } from '@nuxt/kit'; import type { Nitro } from 'nitropack/types'; import * as path from 'path'; import type { InputPluginOption } from 'rollup'; +/** + * Adds a server import for the middleware instrumentation. + */ +export function addMiddlewareImports(): void { + addServerImports([ + { + name: 'wrapMiddlewareHandlerWithSentry', + from: createResolver(import.meta.url).resolve('./runtime/hooks/wrapMiddlewareHandler'), + }, + ]); +} + /** * Adds middleware instrumentation to the Nitro build. * * @param nitro Nitro instance + * @param isNitroV3 Whether the app builds with Nitro v3 (Nuxt 5) */ -export function addMiddlewareInstrumentation(nitro: Nitro): void { +export function addMiddlewareInstrumentation(nitro: Nitro, isNitroV3: boolean): void { nitro.hooks.hook('rollup:before', (nitro, rollupConfig) => { if (!rollupConfig.plugins) { rollupConfig.plugins = []; @@ -18,7 +31,7 @@ export function addMiddlewareInstrumentation(nitro: Nitro): void { rollupConfig.plugins = [rollupConfig.plugins]; } - rollupConfig.plugins.push(middlewareInstrumentationPlugin(nitro)); + rollupConfig.plugins.push(middlewareInstrumentationPlugin(nitro, isNitroV3)); }); } @@ -26,13 +39,12 @@ export function addMiddlewareInstrumentation(nitro: Nitro): void { * Creates a rollup plugin for the middleware instrumentation by transforming the middleware code. * * @param nitro Nitro instance + * @param isNitroV3 Whether the app builds with Nitro v3 (Nuxt 5) * @returns The rollup plugin for the middleware instrumentation. */ -function middlewareInstrumentationPlugin(nitro: Nitro): InputPluginOption { +function middlewareInstrumentationPlugin(nitro: Nitro, isNitroV3: boolean): InputPluginOption { const middlewareFiles = new Set(); - // Imported by absolute path rather than through `#imports`: with `imports.autoImport: false`, - // Nuxt 5 generates an empty server `#imports` module, dropping `addServerImports` registrations. - const wrapperModule = createResolver(import.meta.url).resolve('./runtime/hooks/wrapMiddlewareHandler'); + const wrapperModule = isNitroV3 ? '#imports/server' : '#imports'; return { name: 'sentry-nuxt-middleware-instrumentation', @@ -63,7 +75,7 @@ function middlewareInstrumentationPlugin(nitro: Nitro): InputPluginOption { * * @param originalCode The original user code of the middleware. * @param fileName The name of the middleware file, used for the span name and logging. - * @param wrapperModule Absolute path of the module exporting `wrapMiddlewareHandlerWithSentry`. + * @param wrapperModule Import specifier resolving to `wrapMiddlewareHandlerWithSentry`. * * @returns The wrapped user code of the middleware. */ @@ -72,7 +84,7 @@ function wrapMiddlewareCode(originalCode: string, fileName: string, wrapperModul const cleanFileName = fileName.replace(/\.(ts|js|mjs|mts|cts)$/, ''); return ` -import { wrapMiddlewareHandlerWithSentry } from ${JSON.stringify(wrapperModule)}; +import { wrapMiddlewareHandlerWithSentry } from '${wrapperModule}'; function defineInstrumentedEventHandler(handlerOrObject) { return defineEventHandler(wrapMiddlewareHandlerWithSentry(handlerOrObject, '${cleanFileName}')); From dfd05398f8ee35603420814e048f7d54309f1d6e Mon Sep 17 00:00:00 2001 From: s1gr1d <32902192+s1gr1d@users.noreply.github.com> Date: Tue, 8 Sep 2026 17:09:40 +0200 Subject: [PATCH 3/3] lower minimum release age --- .../e2e-tests/test-applications/nuxt-5/pnpm-workspace.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-packages/e2e-tests/test-applications/nuxt-5/pnpm-workspace.yaml b/dev-packages/e2e-tests/test-applications/nuxt-5/pnpm-workspace.yaml index 227e243b2ee4..4210a62a804d 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-5/pnpm-workspace.yaml +++ b/dev-packages/e2e-tests/test-applications/nuxt-5/pnpm-workspace.yaml @@ -1,2 +1,3 @@ allowBuilds: '@sentry/cli': true +minimumReleaseAge: 0