From 745bb3524b5321fcf92ed3564772b61c2d6ef6f8 Mon Sep 17 00:00:00 2001 From: s1gr1d <32902192+s1gr1d@users.noreply.github.com> Date: Fri, 2 Jan 2026 13:20:39 +0100 Subject: [PATCH 1/6] feat(nuxt): Detect development environment and add dev E2E test --- .../test-applications/nuxt-4/package.json | 5 +- .../nuxt-4/playwright.config.ts | 20 ++++++- .../nuxt-4/tests/environment.test.ts | 55 +++++++++++++++++++ .../nuxt-4/tests/isDevMode.ts | 2 + packages/core/src/constants.ts | 1 + packages/core/src/index.ts | 2 +- packages/nuxt/package.json | 1 + packages/nuxt/src/client/sdk.ts | 4 +- packages/nuxt/src/server/sdk.ts | 14 ++++- 9 files changed, 98 insertions(+), 6 deletions(-) create mode 100644 dev-packages/e2e-tests/test-applications/nuxt-4/tests/environment.test.ts create mode 100644 dev-packages/e2e-tests/test-applications/nuxt-4/tests/isDevMode.ts diff --git a/dev-packages/e2e-tests/test-applications/nuxt-4/package.json b/dev-packages/e2e-tests/test-applications/nuxt-4/package.json index eb28e69b0633..b64166c61702 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-4/package.json +++ b/dev-packages/e2e-tests/test-applications/nuxt-4/package.json @@ -5,15 +5,18 @@ "scripts": { "build": "nuxt build", "dev": "nuxt dev", + "dev:sentry": "NODE_OPTIONS='--import ./.nuxt/dev/sentry.server.config.mjs' nuxt dev", "generate": "nuxt generate", "preview": "nuxt preview", "start": "node .output/server/index.mjs", "start:import": "node --import ./.output/server/sentry.server.config.mjs .output/server/index.mjs", "clean": "npx nuxi cleanup", "test": "playwright test", + "test:prod": "TEST_ENV=production playwright test", + "test:dev": "TEST_ENV=development playwright test", "test:build": "pnpm install && pnpm build", "test:build-canary": "pnpm add nuxt@npm:nuxt-nightly@latest && pnpm add nitropack@npm:nitropack-nightly@latest && pnpm install --force && pnpm build", - "test:assert": "pnpm test" + "test:assert": "pnpm test:prod && pnpm test:dev" }, "dependencies": { "@pinia/nuxt": "^0.5.5", diff --git a/dev-packages/e2e-tests/test-applications/nuxt-4/playwright.config.ts b/dev-packages/e2e-tests/test-applications/nuxt-4/playwright.config.ts index e07fb02e5218..f5079f73202b 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-4/playwright.config.ts +++ b/dev-packages/e2e-tests/test-applications/nuxt-4/playwright.config.ts @@ -1,7 +1,25 @@ import { getPlaywrightConfig } from '@sentry-internal/test-utils'; +const testEnv = process.env.TEST_ENV; + +if (!testEnv) { + throw new Error('No test env defined'); +} + +const getStartCommand = () => { + if (testEnv === 'development') { + return 'pnpm dev'; + } + + if (testEnv === 'production') { + return 'pnpm start:import'; + } + + throw new Error(`Unknown test env: ${testEnv}`); +}; + const config = getPlaywrightConfig({ - startCommand: `pnpm start:import`, + startCommand: getStartCommand(), }); export default config; diff --git a/dev-packages/e2e-tests/test-applications/nuxt-4/tests/environment.test.ts b/dev-packages/e2e-tests/test-applications/nuxt-4/tests/environment.test.ts new file mode 100644 index 000000000000..1b85bd5ea368 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/nuxt-4/tests/environment.test.ts @@ -0,0 +1,55 @@ +import { expect, test } from '@playwright/test'; +import { waitForError, waitForTransaction } from '@sentry-internal/test-utils'; +import { isDevMode } from './isDevMode'; + +test.describe('environment detection', async () => { + test('sets correct environment for application errors', async ({ page }) => { + const errorPromise = waitForError('nuxt-4', async errorEvent => { + return errorEvent?.exception?.values?.[0]?.value === 'Error thrown from Nuxt-4 E2E test app'; + }); + + await page.goto(`/client-error`); + await page.locator('#errorBtn').click(); + + const error = await errorPromise; + + if (isDevMode) { + expect(error.environment).toBe('development'); + } else { + expect(error.environment).toBe('production'); + } + }); + + test('sets correct environment for application transactions', async ({ page }) => { + const transactionPromise = waitForTransaction('nuxt-4', async transactionEvent => { + return transactionEvent.transaction === '/test-param/:param()'; + }); + + await page.goto(`/test-param/1234`); + + const transaction = await transactionPromise; + + if (isDevMode) { + expect(transaction.environment).toBe('development'); + } else { + expect(transaction.environment).toBe('production'); + } + }); + + test('includes environment in event context', async ({ page }) => { + const errorPromise = waitForError('nuxt-4', async errorEvent => { + return errorEvent?.exception?.values?.[0]?.value === 'Error thrown from Nuxt-4 E2E test app'; + }); + + await page.goto(`/client-error`); + await page.locator('#errorBtn').click(); + + const error = await errorPromise; + + if (isDevMode) { + expect(error.environment).toBe('development'); + } else { + expect(error.environment).toBe('production'); + } + }); +}); diff --git a/dev-packages/e2e-tests/test-applications/nuxt-4/tests/isDevMode.ts b/dev-packages/e2e-tests/test-applications/nuxt-4/tests/isDevMode.ts new file mode 100644 index 000000000000..94163ff68beb --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/nuxt-4/tests/isDevMode.ts @@ -0,0 +1,2 @@ +export const isDevMode = !!process.env.TEST_ENV && process.env.TEST_ENV.includes('development'); + diff --git a/packages/core/src/constants.ts b/packages/core/src/constants.ts index 38475b857ace..7fdc380faf0d 100644 --- a/packages/core/src/constants.ts +++ b/packages/core/src/constants.ts @@ -1 +1,2 @@ export const DEFAULT_ENVIRONMENT = 'production'; +export const DEV_ENVIRONMENT = 'development'; diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index c4884edf939b..30e24c3b35c7 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -101,7 +101,7 @@ export { headersToDict, httpHeadersToSpanAttributes, } from './utils/request'; -export { DEFAULT_ENVIRONMENT } from './constants'; +export { DEFAULT_ENVIRONMENT, DEV_ENVIRONMENT } from './constants'; export { addBreadcrumb } from './breadcrumbs'; export { functionToStringIntegration } from './integrations/functiontostring'; // eslint-disable-next-line deprecation/deprecation diff --git a/packages/nuxt/package.json b/packages/nuxt/package.json index bbb4086d3dc2..37e6e52c1477 100644 --- a/packages/nuxt/package.json +++ b/packages/nuxt/package.json @@ -53,6 +53,7 @@ "@sentry/cloudflare": "10.32.1", "@sentry/core": "10.32.1", "@sentry/node": "10.32.1", + "@sentry/node-core": "10.32.1", "@sentry/rollup-plugin": "^4.6.1", "@sentry/vite-plugin": "^4.6.1", "@sentry/vue": "10.32.1" diff --git a/packages/nuxt/src/client/sdk.ts b/packages/nuxt/src/client/sdk.ts index 5db856dae689..4c683272ade2 100644 --- a/packages/nuxt/src/client/sdk.ts +++ b/packages/nuxt/src/client/sdk.ts @@ -1,6 +1,7 @@ import { getDefaultIntegrations as getBrowserDefaultIntegrations, init as initBrowser } from '@sentry/browser'; import type { Client } from '@sentry/core'; -import { applySdkMetadata } from '@sentry/core'; +import { applySdkMetadata, DEFAULT_ENVIRONMENT, DEV_ENVIRONMENT } from '@sentry/core'; +import { isCjs } from '@sentry/node-core'; import type { SentryNuxtClientOptions } from '../common/types'; /** @@ -12,6 +13,7 @@ export function init(options: SentryNuxtClientOptions): Client | undefined { const sentryOptions = { /* BrowserTracing is added later with the Nuxt client plugin */ defaultIntegrations: [...getBrowserDefaultIntegrations(options)], + environment: !isCjs() && import.meta.dev ? DEV_ENVIRONMENT : DEFAULT_ENVIRONMENT, ...options, }; diff --git a/packages/nuxt/src/server/sdk.ts b/packages/nuxt/src/server/sdk.ts index 2b492b1249ac..e70d637b6b4b 100644 --- a/packages/nuxt/src/server/sdk.ts +++ b/packages/nuxt/src/server/sdk.ts @@ -1,12 +1,21 @@ import * as path from 'node:path'; import type { Client, Event, EventProcessor, Integration } from '@sentry/core'; -import { applySdkMetadata, debug, flush, getGlobalScope, vercelWaitUntil } from '@sentry/core'; +import { + applySdkMetadata, + debug, + DEFAULT_ENVIRONMENT, + DEV_ENVIRONMENT, + flush, + getGlobalScope, + vercelWaitUntil, +} from '@sentry/core'; import { getDefaultIntegrations as getDefaultNodeIntegrations, httpIntegration, init as initNode, type NodeOptions, } from '@sentry/node'; +import { isCjs } from '@sentry/node-core'; import { DEBUG_BUILD } from '../common/debug-build'; import type { SentryNuxtServerOptions } from '../common/types'; @@ -17,8 +26,9 @@ import type { SentryNuxtServerOptions } from '../common/types'; */ export function init(options: SentryNuxtServerOptions): Client | undefined { const sentryOptions = { - ...options, defaultIntegrations: getNuxtDefaultIntegrations(options), + environment: !isCjs() && import.meta.dev ? DEV_ENVIRONMENT : DEFAULT_ENVIRONMENT, + ...options, }; applySdkMetadata(sentryOptions, 'nuxt', ['nuxt', 'node']); From 9bbb13c7a8357e726417728ad3aa043a4a0d2d15 Mon Sep 17 00:00:00 2001 From: s1gr1d <32902192+s1gr1d@users.noreply.github.com> Date: Fri, 2 Jan 2026 13:23:08 +0100 Subject: [PATCH 2/6] add contributor --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e8fdc6d9fb1d..7b9d0f765950 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ - "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott -Work in this release was contributed by @xgedev, @Mohataseem89, @sebws, and @G-Rath. Thank you for your contributions! +Work in this release was contributed by @xgedev, @Mohataseem89, @sebws, @maximepvrt and @G-Rath. Thank you for your contributions! - ref(nextjs): Drop `resolve` dependency from the Next.js SDK ([#18618](https://github.com/getsentry/sentry-javascript/pull/18618)) From e463c3dec67ba19c1b7ba5ac68d97cdb037af7c1 Mon Sep 17 00:00:00 2001 From: s1gr1d <32902192+s1gr1d@users.noreply.github.com> Date: Fri, 2 Jan 2026 13:29:59 +0100 Subject: [PATCH 3/6] remove node import from client --- packages/nuxt/src/client/sdk.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/nuxt/src/client/sdk.ts b/packages/nuxt/src/client/sdk.ts index 4c683272ade2..f0654a97c201 100644 --- a/packages/nuxt/src/client/sdk.ts +++ b/packages/nuxt/src/client/sdk.ts @@ -1,7 +1,6 @@ import { getDefaultIntegrations as getBrowserDefaultIntegrations, init as initBrowser } from '@sentry/browser'; import type { Client } from '@sentry/core'; import { applySdkMetadata, DEFAULT_ENVIRONMENT, DEV_ENVIRONMENT } from '@sentry/core'; -import { isCjs } from '@sentry/node-core'; import type { SentryNuxtClientOptions } from '../common/types'; /** @@ -13,7 +12,7 @@ export function init(options: SentryNuxtClientOptions): Client | undefined { const sentryOptions = { /* BrowserTracing is added later with the Nuxt client plugin */ defaultIntegrations: [...getBrowserDefaultIntegrations(options)], - environment: !isCjs() && import.meta.dev ? DEV_ENVIRONMENT : DEFAULT_ENVIRONMENT, + environment: import.meta.dev ? DEV_ENVIRONMENT : DEFAULT_ENVIRONMENT, ...options, }; From f582ec27b234a6dd11d993fc9fda356ab2e84ccd Mon Sep 17 00:00:00 2001 From: s1gr1d <32902192+s1gr1d@users.noreply.github.com> Date: Fri, 2 Jan 2026 16:10:05 +0100 Subject: [PATCH 4/6] add E2E test setup for dev --- .../nuxt-4/nuxt-start-dev-server.bash | 32 +++++++++++++++++++ .../test-applications/nuxt-4/package.json | 3 +- .../nuxt-4/playwright.config.ts | 2 +- .../nuxt-4/sentry.client.config.ts | 1 - .../nuxt-4/sentry.server.config.ts | 1 - .../nuxt-4/tests/environment.test.ts | 20 ++---------- .../nuxt-4/tests/isDevMode.ts | 1 - 7 files changed, 36 insertions(+), 24 deletions(-) create mode 100644 dev-packages/e2e-tests/test-applications/nuxt-4/nuxt-start-dev-server.bash diff --git a/dev-packages/e2e-tests/test-applications/nuxt-4/nuxt-start-dev-server.bash b/dev-packages/e2e-tests/test-applications/nuxt-4/nuxt-start-dev-server.bash new file mode 100644 index 000000000000..747893ab6632 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/nuxt-4/nuxt-start-dev-server.bash @@ -0,0 +1,32 @@ +#!/bin/bash +# To enable Sentry in Nuxt dev, it needs the sentry.server.config.mjs file from the .nuxt folder. +# First, we need to start 'nuxt dev' to generate the file, and then start 'nuxt dev' again with the NODE_OPTIONS to have Sentry enabled. + +# 1. Start dev in background - this generates .nuxt folder +# Using a different port to avoid playwright already starting with the tests for port 3030 +pnpm dev -p 3035 & +DEV_PID=$! + +# 2. Wait for the sentry.server.config.mjs file to appear +echo "Waiting for .nuxt/dev/sentry.server.config.mjs file..." +COUNTER=0 +while [ ! -f ".nuxt/dev/sentry.server.config.mjs" ] && [ $COUNTER -lt 30 ]; do + sleep 1 + ((COUNTER++)) +done + +if [ ! -f ".nuxt/dev/sentry.server.config.mjs" ]; then + echo "ERROR: .nuxt/dev/sentry.server.config.mjs file never appeared!" + pkill -P $DEV_PID || kill $DEV_PID || pkill -f "nuxt" + exit 1 +fi + +# 3. Cleanup +echo "Found .nuxt/dev/sentry.server.config.mjs, stopping 'nuxt dev' process..." +pkill -P $DEV_PID || kill $DEV_PID || pkill -f "nuxt" +sleep 2 # Give it a moment to release ports + +echo "Starting nuxt dev with Sentry server config..." + +# 4. Start the actual dev command which should be used for the tests +NODE_OPTIONS='--import ./.nuxt/dev/sentry.server.config.mjs' nuxt dev diff --git a/dev-packages/e2e-tests/test-applications/nuxt-4/package.json b/dev-packages/e2e-tests/test-applications/nuxt-4/package.json index b64166c61702..ebd383e48eb9 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-4/package.json +++ b/dev-packages/e2e-tests/test-applications/nuxt-4/package.json @@ -5,7 +5,6 @@ "scripts": { "build": "nuxt build", "dev": "nuxt dev", - "dev:sentry": "NODE_OPTIONS='--import ./.nuxt/dev/sentry.server.config.mjs' nuxt dev", "generate": "nuxt generate", "preview": "nuxt preview", "start": "node .output/server/index.mjs", @@ -13,7 +12,7 @@ "clean": "npx nuxi cleanup", "test": "playwright test", "test:prod": "TEST_ENV=production playwright test", - "test:dev": "TEST_ENV=development playwright test", + "test:dev": "TEST_ENV=development playwright test environment", "test:build": "pnpm install && pnpm build", "test:build-canary": "pnpm add nuxt@npm:nuxt-nightly@latest && pnpm add nitropack@npm:nitropack-nightly@latest && pnpm install --force && pnpm build", "test:assert": "pnpm test:prod && pnpm test:dev" diff --git a/dev-packages/e2e-tests/test-applications/nuxt-4/playwright.config.ts b/dev-packages/e2e-tests/test-applications/nuxt-4/playwright.config.ts index f5079f73202b..d3618f176d02 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-4/playwright.config.ts +++ b/dev-packages/e2e-tests/test-applications/nuxt-4/playwright.config.ts @@ -8,7 +8,7 @@ if (!testEnv) { const getStartCommand = () => { if (testEnv === 'development') { - return 'pnpm dev'; + return 'bash ./nuxt-start-dev-server.bash'; } if (testEnv === 'production') { diff --git a/dev-packages/e2e-tests/test-applications/nuxt-4/sentry.client.config.ts b/dev-packages/e2e-tests/test-applications/nuxt-4/sentry.client.config.ts index 3cbea64827cb..7b5d97ff0b09 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-4/sentry.client.config.ts +++ b/dev-packages/e2e-tests/test-applications/nuxt-4/sentry.client.config.ts @@ -2,7 +2,6 @@ import * as Sentry from '@sentry/nuxt'; import { usePinia, useRuntimeConfig } from '#imports'; Sentry.init({ - environment: 'qa', // dynamic sampling bias to keep transactions dsn: useRuntimeConfig().public.sentry.dsn, tunnel: `http://localhost:3031/`, // proxy server tracesSampleRate: 1.0, diff --git a/dev-packages/e2e-tests/test-applications/nuxt-4/sentry.server.config.ts b/dev-packages/e2e-tests/test-applications/nuxt-4/sentry.server.config.ts index 729b2296c683..26519911072b 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-4/sentry.server.config.ts +++ b/dev-packages/e2e-tests/test-applications/nuxt-4/sentry.server.config.ts @@ -2,7 +2,6 @@ import * as Sentry from '@sentry/nuxt'; Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', - environment: 'qa', // dynamic sampling bias to keep transactions tracesSampleRate: 1.0, // Capture 100% of the transactions tunnel: 'http://localhost:3031/', // proxy server }); diff --git a/dev-packages/e2e-tests/test-applications/nuxt-4/tests/environment.test.ts b/dev-packages/e2e-tests/test-applications/nuxt-4/tests/environment.test.ts index 1b85bd5ea368..f0aa2fd51535 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-4/tests/environment.test.ts +++ b/dev-packages/e2e-tests/test-applications/nuxt-4/tests/environment.test.ts @@ -8,7 +8,8 @@ test.describe('environment detection', async () => { return errorEvent?.exception?.values?.[0]?.value === 'Error thrown from Nuxt-4 E2E test app'; }); - await page.goto(`/client-error`); + // We have to wait for networkidle in dev mode because clicking the button is a no-op otherwise (network requests are blocked during page load) + await page.goto(`/client-error`, isDevMode ? { waitUntil: 'networkidle' } : {}); await page.locator('#errorBtn').click(); const error = await errorPromise; @@ -35,21 +36,4 @@ test.describe('environment detection', async () => { expect(transaction.environment).toBe('production'); } }); - - test('includes environment in event context', async ({ page }) => { - const errorPromise = waitForError('nuxt-4', async errorEvent => { - return errorEvent?.exception?.values?.[0]?.value === 'Error thrown from Nuxt-4 E2E test app'; - }); - - await page.goto(`/client-error`); - await page.locator('#errorBtn').click(); - - const error = await errorPromise; - - if (isDevMode) { - expect(error.environment).toBe('development'); - } else { - expect(error.environment).toBe('production'); - } - }); }); diff --git a/dev-packages/e2e-tests/test-applications/nuxt-4/tests/isDevMode.ts b/dev-packages/e2e-tests/test-applications/nuxt-4/tests/isDevMode.ts index 94163ff68beb..d2be94232110 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-4/tests/isDevMode.ts +++ b/dev-packages/e2e-tests/test-applications/nuxt-4/tests/isDevMode.ts @@ -1,2 +1 @@ export const isDevMode = !!process.env.TEST_ENV && process.env.TEST_ENV.includes('development'); - From a35268daa3cd530029f73d446bece4a16b4b6a09 Mon Sep 17 00:00:00 2001 From: s1gr1d <32902192+s1gr1d@users.noreply.github.com> Date: Wed, 7 Jan 2026 14:56:23 +0100 Subject: [PATCH 5/6] add tests for server-side; modify bash script --- .../nuxt-4/nuxt-start-dev-server.bash | 27 +++++++++--- .../nuxt-4/tests/environment.test.ts | 42 ++++++++++++++++++- 2 files changed, 62 insertions(+), 7 deletions(-) diff --git a/dev-packages/e2e-tests/test-applications/nuxt-4/nuxt-start-dev-server.bash b/dev-packages/e2e-tests/test-applications/nuxt-4/nuxt-start-dev-server.bash index 747893ab6632..1204eabb7c87 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-4/nuxt-start-dev-server.bash +++ b/dev-packages/e2e-tests/test-applications/nuxt-4/nuxt-start-dev-server.bash @@ -2,9 +2,11 @@ # To enable Sentry in Nuxt dev, it needs the sentry.server.config.mjs file from the .nuxt folder. # First, we need to start 'nuxt dev' to generate the file, and then start 'nuxt dev' again with the NODE_OPTIONS to have Sentry enabled. +# Using a different port to avoid playwright already starting with the tests for port 3030 +TEMP_PORT=3035 + # 1. Start dev in background - this generates .nuxt folder -# Using a different port to avoid playwright already starting with the tests for port 3030 -pnpm dev -p 3035 & +pnpm dev -p $TEMP_PORT & DEV_PID=$! # 2. Wait for the sentry.server.config.mjs file to appear @@ -17,14 +19,29 @@ done if [ ! -f ".nuxt/dev/sentry.server.config.mjs" ]; then echo "ERROR: .nuxt/dev/sentry.server.config.mjs file never appeared!" - pkill -P $DEV_PID || kill $DEV_PID || pkill -f "nuxt" + echo "This usually means the Nuxt dev server failed to start or generate the file. Try to rerun the test." + pkill -P $DEV_PID || kill $DEV_PID exit 1 fi # 3. Cleanup echo "Found .nuxt/dev/sentry.server.config.mjs, stopping 'nuxt dev' process..." -pkill -P $DEV_PID || kill $DEV_PID || pkill -f "nuxt" -sleep 2 # Give it a moment to release ports +pkill -P $DEV_PID || kill $DEV_PID + +# Wait for port to be released +echo "Waiting for port $TEMP_PORT to be released..." +COUNTER=0 +# Check if port is still in use +while lsof -i :$TEMP_PORT > /dev/null 2>&1 && [ $COUNTER -lt 10 ]; do + sleep 1 + ((COUNTER++)) +done + +if lsof -i :$TEMP_PORT > /dev/null 2>&1; then + echo "WARNING: Port $TEMP_PORT still in use after 10 seconds, proceeding anyway..." +else + echo "Port $TEMP_PORT released successfully" +fi echo "Starting nuxt dev with Sentry server config..." diff --git a/dev-packages/e2e-tests/test-applications/nuxt-4/tests/environment.test.ts b/dev-packages/e2e-tests/test-applications/nuxt-4/tests/environment.test.ts index f0aa2fd51535..b59e4560165b 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-4/tests/environment.test.ts +++ b/dev-packages/e2e-tests/test-applications/nuxt-4/tests/environment.test.ts @@ -3,7 +3,7 @@ import { waitForError, waitForTransaction } from '@sentry-internal/test-utils'; import { isDevMode } from './isDevMode'; test.describe('environment detection', async () => { - test('sets correct environment for application errors', async ({ page }) => { + test('sets correct environment for client-side errors', async ({ page }) => { const errorPromise = waitForError('nuxt-4', async errorEvent => { return errorEvent?.exception?.values?.[0]?.value === 'Error thrown from Nuxt-4 E2E test app'; }); @@ -21,7 +21,7 @@ test.describe('environment detection', async () => { } }); - test('sets correct environment for application transactions', async ({ page }) => { + test('sets correct environment for client-side transactions', async ({ page }) => { const transactionPromise = waitForTransaction('nuxt-4', async transactionEvent => { return transactionEvent.transaction === '/test-param/:param()'; }); @@ -36,4 +36,42 @@ test.describe('environment detection', async () => { expect(transaction.environment).toBe('production'); } }); + + test('sets correct environment for server-side errors', async ({ page }) => { + const errorPromise = waitForError('nuxt-4', async errorEvent => { + return errorEvent?.exception?.values?.[0]?.value === 'Nuxt 4 Server error'; + }); + + await page.goto(`/fetch-server-routes`, isDevMode ? { waitUntil: 'networkidle' } : {}); + await page.getByText('Fetch Server API Error', { exact: true }).click(); + + const error = await errorPromise; + + expect(error.transaction).toBe('GET /api/server-error'); + + if (isDevMode) { + expect(error.environment).toBe('development'); + } else { + expect(error.environment).toBe('production'); + } + }); + + test('sets correct environment for server-side transactions', async ({ page }) => { + const transactionPromise = waitForTransaction('nuxt-4', async transactionEvent => { + return transactionEvent.transaction === 'GET /api/nitro-fetch'; + }); + + await page.goto(`/fetch-server-routes`, isDevMode ? { waitUntil: 'networkidle' } : {}); + await page.getByText('Fetch Nitro $fetch', { exact: true }).click(); + + const transaction = await transactionPromise; + + expect(transaction.contexts.trace.op).toBe('http.server'); + + if (isDevMode) { + expect(transaction.environment).toBe('development'); + } else { + expect(transaction.environment).toBe('production'); + } + }); }); From 17a2f13ec1a3d90374f33a3f958ceeed86b677da Mon Sep 17 00:00:00 2001 From: s1gr1d <32902192+s1gr1d@users.noreply.github.com> Date: Wed, 7 Jan 2026 14:57:49 +0100 Subject: [PATCH 6/6] reorder options --- packages/nuxt/src/server/sdk.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nuxt/src/server/sdk.ts b/packages/nuxt/src/server/sdk.ts index e70d637b6b4b..2621f3f77f9a 100644 --- a/packages/nuxt/src/server/sdk.ts +++ b/packages/nuxt/src/server/sdk.ts @@ -26,9 +26,9 @@ import type { SentryNuxtServerOptions } from '../common/types'; */ export function init(options: SentryNuxtServerOptions): Client | undefined { const sentryOptions = { - defaultIntegrations: getNuxtDefaultIntegrations(options), environment: !isCjs() && import.meta.dev ? DEV_ENVIRONMENT : DEFAULT_ENVIRONMENT, ...options, + defaultIntegrations: getNuxtDefaultIntegrations(options), }; applySdkMetadata(sentryOptions, 'nuxt', ['nuxt', 'node']);