diff --git a/CHANGELOG.md b/CHANGELOG.md
index 30abc26e733c..58c1bf71dce9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,9 +2,104 @@
## Unreleased
-- "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott
+- feat(browser): Add environment variable support for Spotlight configuration ([#18198](https://github.com/getsentry/sentry-javascript/pull/18198))
+ - `SENTRY_SPOTLIGHT`, `PUBLIC_SENTRY_SPOTLIGHT`, `NEXT_PUBLIC_SENTRY_SPOTLIGHT`, `VITE_SENTRY_SPOTLIGHT`, `NUXT_PUBLIC_SENTRY_SPOTLIGHT`, `REACT_APP_SENTRY_SPOTLIGHT`, `VUE_APP_SENTRY_SPOTLIGHT`, and `GATSBY_SENTRY_SPOTLIGHT`
-- fix(node): Fix Spotlight configuration precedence to match specification (#18195)
+## 10.26.0
+
+### Important Changes
+
+- **feat(core): Instrument LangGraph Agent ([#18114](https://github.com/getsentry/sentry-javascript/pull/18114))**
+
+Adds support for instrumenting LangGraph StateGraph operations in Node. The LangGraph integration can be configured as follows:
+
+```js
+Sentry.init({
+ dsn: '__DSN__',
+ sendDefaultPii: false, // Even with PII disabled globally
+ integrations: [
+ Sentry.langGraphIntegration({
+ recordInputs: true, // Force recording input messages
+ recordOutputs: true, // Force recording response text
+ }),
+ ],
+});
+```
+
+- **feat(cloudflare/vercel-edge): Add manual instrumentation for LangGraph ([#18112](https://github.com/getsentry/sentry-javascript/pull/18112))**
+
+Instrumentation for LangGraph in Cloudflare Workers and Vercel Edge environments is supported by manually calling `instrumentLangGraph`:
+
+```js
+import * as Sentry from '@sentry/cloudflare'; // or '@sentry/vercel-edge'
+import { StateGraph, START, END, MessagesAnnotation } from '@langchain/langgraph';
+
+// Create and instrument the graph
+const graph = new StateGraph(MessagesAnnotation)
+ .addNode('agent', agentFn)
+ .addEdge(START, 'agent')
+ .addEdge('agent', END);
+
+Sentry.instrumentLangGraph(graph, {
+ recordInputs: true,
+ recordOutputs: true,
+});
+
+const compiled = graph.compile({ name: 'weather_assistant' });
+
+await compiled.invoke({
+ messages: [{ role: 'user', content: 'What is the weather in SF?' }],
+});
+```
+
+- **feat(node): Add OpenAI SDK v6 support ([#18244](https://github.com/getsentry/sentry-javascript/pull/18244))**
+
+### Other Changes
+
+- feat(core): Support OpenAI embeddings API ([#18224](https://github.com/getsentry/sentry-javascript/pull/18224))
+- feat(browser-utils): bump web-vitals to 5.1.0 ([#18091](https://github.com/getsentry/sentry-javascript/pull/18091))
+- feat(core): Support truncation for LangChain integration request messages ([#18157](https://github.com/getsentry/sentry-javascript/pull/18157))
+- feat(metrics): Add default `server.address` attribute on server runtimes ([#18242](https://github.com/getsentry/sentry-javascript/pull/18242))
+- feat(nextjs): Add URL to server-side transaction events ([#18230](https://github.com/getsentry/sentry-javascript/pull/18230))
+- feat(node-core): Add mechanism to prevent wrapping ai providers multiple times([#17972](https://github.com/getsentry/sentry-javascript/pull/17972))
+- feat(replay): Bump limit for minReplayDuration ([#18190](https://github.com/getsentry/sentry-javascript/pull/18190))
+- fix(browser): Add `ok` status to successful `idleSpan`s ([#18139](https://github.com/getsentry/sentry-javascript/pull/18139))
+- fix(core): Check `fetch` support with data URL ([#18225](https://github.com/getsentry/sentry-javascript/pull/18225))
+- fix(core): Decrease number of Sentry stack frames for messages from `captureConsoleIntegration` ([#18096](https://github.com/getsentry/sentry-javascript/pull/18096))
+- fix(core): Emit processed metric ([#18222](https://github.com/getsentry/sentry-javascript/pull/18222))
+- fix(core): Ensure logs past `MAX_LOG_BUFFER_SIZE` are not swallowed ([#18207](https://github.com/getsentry/sentry-javascript/pull/18207))
+- fix(core): Ensure metrics past `MAX_METRIC_BUFFER_SIZE` are not swallowed ([#18212](https://github.com/getsentry/sentry-javascript/pull/18212))
+- fix(core): Fix logs and metrics flush timeout starvation with continuous logging ([#18211](https://github.com/getsentry/sentry-javascript/pull/18211))
+- fix(core): Flatten gen_ai.request.available_tools in google-genai ([#18194](https://github.com/getsentry/sentry-javascript/pull/18194))
+- fix(core): Stringify available tools sent from vercelai ([#18197](https://github.com/getsentry/sentry-javascript/pull/18197))
+- fix(core/vue): Detect and skip normalizing Vue `VNode` objects with high `normalizeDepth` ([#18206](https://github.com/getsentry/sentry-javascript/pull/18206))
+- fix(nextjs): Avoid wrapping middleware files when in standalone mode ([#18172](https://github.com/getsentry/sentry-javascript/pull/18172))
+- fix(nextjs): Drop meta trace tags if rendered page is ISR ([#18192](https://github.com/getsentry/sentry-javascript/pull/18192))
+- fix(nextjs): Respect PORT variable for dev error symbolication ([#18227](https://github.com/getsentry/sentry-javascript/pull/18227))
+- fix(nextjs): use LRU map instead of map for ISR route cache ([#18234](https://github.com/getsentry/sentry-javascript/pull/18234))
+- fix(node): `tracingChannel` export missing in older node versions ([#18191](https://github.com/getsentry/sentry-javascript/pull/18191))
+- fix(node): Fix Spotlight configuration precedence to match specification ([#18195](https://github.com/getsentry/sentry-javascript/pull/18195))
+- fix(react): Prevent navigation span leaks for consecutive navigations ([#18098](https://github.com/getsentry/sentry-javascript/pull/18098))
+- ref(react-router): Deprecate ErrorBoundary exports ([#18208](https://github.com/getsentry/sentry-javascript/pull/18208))
+
+
+ Internal Changes
+
+- chore: Fix missing changelog quote we use for attribution placement ([#18237](https://github.com/getsentry/sentry-javascript/pull/18237))
+- chore: move tip about prioritizing issues ([#18071](https://github.com/getsentry/sentry-javascript/pull/18071))
+- chore(e2e): Pin `@embroider/addon-shim` to 1.10.0 for the e2e ember-embroider ([#18173](https://github.com/getsentry/sentry-javascript/pull/18173))
+- chore(react-router): Fix casing on deprecation notices ([#18221](https://github.com/getsentry/sentry-javascript/pull/18221))
+- chore(test): Use correct `testTimeout` field in bundler-tests vitest config
+- chore(e2e): Bump zod in e2e tests ([#18251](https://github.com/getsentry/sentry-javascript/pull/18251))
+- test(browser-integration): Fix incorrect tag value assertions ([#18162](https://github.com/getsentry/sentry-javascript/pull/18162))
+- test(profiling): Add test utils to validate Profile Chunk envelope ([#18170](https://github.com/getsentry/sentry-javascript/pull/18170))
+- ref(e2e-ember): Remove `@embroider/addon-shim` override ([#18180](https://github.com/getsentry/sentry-javascript/pull/18180))
+- ref(browser): Move trace lifecycle listeners to class function ([#18231](https://github.com/getsentry/sentry-javascript/pull/18231))
+- ref(browserprofiling): Move and rename profiler class to UIProfiler ([#18187](https://github.com/getsentry/sentry-javascript/pull/18187))
+- ref(core): Move ai integrations from utils to tracing ([#18185](https://github.com/getsentry/sentry-javascript/pull/18185))
+- ref(core): Optimize `Scope.setTag` bundle size and adjust test ([#18182](https://github.com/getsentry/sentry-javascript/pull/18182))
+
+
## 10.25.0
diff --git a/dev-packages/browser-integration-tests/package.json b/dev-packages/browser-integration-tests/package.json
index b6a7e01e7bfb..6350a0826572 100644
--- a/dev-packages/browser-integration-tests/package.json
+++ b/dev-packages/browser-integration-tests/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry-internal/browser-integration-tests",
- "version": "10.25.0",
+ "version": "10.26.0",
"main": "index.js",
"license": "MIT",
"engines": {
@@ -43,7 +43,7 @@
"@babel/preset-typescript": "^7.16.7",
"@playwright/test": "~1.53.2",
"@sentry-internal/rrweb": "2.34.0",
- "@sentry/browser": "10.25.0",
+ "@sentry/browser": "10.26.0",
"@supabase/supabase-js": "2.49.3",
"axios": "^1.12.2",
"babel-loader": "^8.2.2",
diff --git a/dev-packages/bundle-analyzer-scenarios/package.json b/dev-packages/bundle-analyzer-scenarios/package.json
index 5de03ee2a113..72928caf3708 100644
--- a/dev-packages/bundle-analyzer-scenarios/package.json
+++ b/dev-packages/bundle-analyzer-scenarios/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry-internal/bundle-analyzer-scenarios",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Scenarios to test bundle analysis with",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/dev-packages/bundle-analyzer-scenarios",
diff --git a/dev-packages/bundler-tests/package.json b/dev-packages/bundler-tests/package.json
index a7850b3c1cc6..14bfa512f433 100644
--- a/dev-packages/bundler-tests/package.json
+++ b/dev-packages/bundler-tests/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry-internal/bundler-tests",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Bundler tests for Sentry Browser SDK",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/bundler-tests",
@@ -13,7 +13,7 @@
},
"dependencies": {
"@rollup/plugin-node-resolve": "^15.2.3",
- "@sentry/browser": "10.25.0",
+ "@sentry/browser": "10.26.0",
"rollup": "^4.0.0",
"vite": "^5.0.0",
"vitest": "^3.2.4",
diff --git a/dev-packages/clear-cache-gh-action/package.json b/dev-packages/clear-cache-gh-action/package.json
index c64bdf36eb9a..22f0c16d2680 100644
--- a/dev-packages/clear-cache-gh-action/package.json
+++ b/dev-packages/clear-cache-gh-action/package.json
@@ -1,7 +1,7 @@
{
"name": "@sentry-internal/clear-cache-gh-action",
"description": "An internal Github Action to clear GitHub caches.",
- "version": "10.25.0",
+ "version": "10.26.0",
"license": "MIT",
"engines": {
"node": ">=18"
diff --git a/dev-packages/cloudflare-integration-tests/package.json b/dev-packages/cloudflare-integration-tests/package.json
index c791a224a2cc..e4af74f7edfe 100644
--- a/dev-packages/cloudflare-integration-tests/package.json
+++ b/dev-packages/cloudflare-integration-tests/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry-internal/cloudflare-integration-tests",
- "version": "10.25.0",
+ "version": "10.26.0",
"license": "MIT",
"engines": {
"node": ">=18"
@@ -13,12 +13,12 @@
"test:watch": "yarn test --watch"
},
"dependencies": {
- "@sentry/cloudflare": "10.25.0",
- "@langchain/langgraph": "^1.0.1"
+ "@langchain/langgraph": "^1.0.1",
+ "@sentry/cloudflare": "10.26.0"
},
"devDependencies": {
"@cloudflare/workers-types": "^4.20250922.0",
- "@sentry-internal/test-utils": "10.25.0",
+ "@sentry-internal/test-utils": "10.26.0",
"eslint-plugin-regexp": "^1.15.0",
"vitest": "^3.2.4",
"wrangler": "4.22.0"
diff --git a/dev-packages/e2e-tests/package.json b/dev-packages/e2e-tests/package.json
index 556891ca2d55..7712bbac10ee 100644
--- a/dev-packages/e2e-tests/package.json
+++ b/dev-packages/e2e-tests/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry-internal/e2e-tests",
- "version": "10.25.0",
+ "version": "10.26.0",
"license": "MIT",
"private": true,
"scripts": {
diff --git a/dev-packages/external-contributor-gh-action/package.json b/dev-packages/external-contributor-gh-action/package.json
index 4b536a69fc1d..9e99c2b66ae0 100644
--- a/dev-packages/external-contributor-gh-action/package.json
+++ b/dev-packages/external-contributor-gh-action/package.json
@@ -1,7 +1,7 @@
{
"name": "@sentry-internal/external-contributor-gh-action",
"description": "An internal Github Action to add external contributors to the CHANGELOG.md file.",
- "version": "10.25.0",
+ "version": "10.26.0",
"license": "MIT",
"engines": {
"node": ">=18"
diff --git a/dev-packages/node-core-integration-tests/package.json b/dev-packages/node-core-integration-tests/package.json
index bf4bf9f3578a..fe755f16cc6d 100644
--- a/dev-packages/node-core-integration-tests/package.json
+++ b/dev-packages/node-core-integration-tests/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry-internal/node-core-integration-tests",
- "version": "10.25.0",
+ "version": "10.26.0",
"license": "MIT",
"engines": {
"node": ">=18"
@@ -34,8 +34,8 @@
"@opentelemetry/resources": "^2.1.0",
"@opentelemetry/sdk-trace-base": "^2.1.0",
"@opentelemetry/semantic-conventions": "^1.37.0",
- "@sentry/core": "10.25.0",
- "@sentry/node-core": "10.25.0",
+ "@sentry/core": "10.26.0",
+ "@sentry/node-core": "10.26.0",
"body-parser": "^1.20.3",
"cors": "^2.8.5",
"cron": "^3.1.6",
diff --git a/dev-packages/node-integration-tests/package.json b/dev-packages/node-integration-tests/package.json
index 0bc5b8b83b1c..1799e7c9b306 100644
--- a/dev-packages/node-integration-tests/package.json
+++ b/dev-packages/node-integration-tests/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry-internal/node-integration-tests",
- "version": "10.25.0",
+ "version": "10.26.0",
"license": "MIT",
"engines": {
"node": ">=18"
@@ -36,9 +36,9 @@
"@nestjs/core": "^11",
"@nestjs/platform-express": "^11",
"@prisma/client": "6.15.0",
- "@sentry/aws-serverless": "10.25.0",
- "@sentry/core": "10.25.0",
- "@sentry/node": "10.25.0",
+ "@sentry/aws-serverless": "10.26.0",
+ "@sentry/core": "10.26.0",
+ "@sentry/node": "10.26.0",
"@types/mongodb": "^3.6.20",
"@types/mysql": "^2.15.21",
"@types/pg": "^8.6.5",
@@ -83,7 +83,7 @@
"yargs": "^16.2.0"
},
"devDependencies": {
- "@sentry-internal/test-utils": "10.25.0",
+ "@sentry-internal/test-utils": "10.26.0",
"@types/amqplib": "^0.10.5",
"@types/node-cron": "^3.0.11",
"@types/node-schedule": "^2.1.7",
diff --git a/dev-packages/node-overhead-gh-action/package.json b/dev-packages/node-overhead-gh-action/package.json
index 02dca29a291f..498cefecf053 100644
--- a/dev-packages/node-overhead-gh-action/package.json
+++ b/dev-packages/node-overhead-gh-action/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry-internal/node-overhead-gh-action",
- "version": "10.25.0",
+ "version": "10.26.0",
"license": "MIT",
"engines": {
"node": ">=18"
@@ -23,7 +23,7 @@
"fix": "eslint . --format stylish --fix"
},
"dependencies": {
- "@sentry/node": "10.25.0",
+ "@sentry/node": "10.26.0",
"express": "^4.21.1",
"mysql2": "^3.14.4"
},
diff --git a/dev-packages/rollup-utils/package.json b/dev-packages/rollup-utils/package.json
index 60237502ec71..62cec9c7f9f9 100644
--- a/dev-packages/rollup-utils/package.json
+++ b/dev-packages/rollup-utils/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry-internal/rollup-utils",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Rollup utilities used at Sentry for the Sentry JavaScript SDK",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/rollup-utils",
diff --git a/dev-packages/size-limit-gh-action/package.json b/dev-packages/size-limit-gh-action/package.json
index e29d747dcbaa..5de80ac560c7 100644
--- a/dev-packages/size-limit-gh-action/package.json
+++ b/dev-packages/size-limit-gh-action/package.json
@@ -1,7 +1,7 @@
{
"name": "@sentry-internal/size-limit-gh-action",
"description": "An internal Github Action to compare the current size of a PR against the one on develop.",
- "version": "10.25.0",
+ "version": "10.26.0",
"license": "MIT",
"engines": {
"node": ">=18"
diff --git a/dev-packages/test-utils/package.json b/dev-packages/test-utils/package.json
index c8c0c09b353d..7d0400748c94 100644
--- a/dev-packages/test-utils/package.json
+++ b/dev-packages/test-utils/package.json
@@ -1,6 +1,6 @@
{
"private": true,
- "version": "10.25.0",
+ "version": "10.26.0",
"name": "@sentry-internal/test-utils",
"author": "Sentry",
"license": "MIT",
@@ -48,7 +48,7 @@
},
"devDependencies": {
"@playwright/test": "~1.53.2",
- "@sentry/core": "10.25.0",
+ "@sentry/core": "10.26.0",
"eslint-plugin-regexp": "^1.15.0"
},
"volta": {
diff --git a/lerna.json b/lerna.json
index 3b70b74ac476..7363d9e257e2 100644
--- a/lerna.json
+++ b/lerna.json
@@ -1,5 +1,5 @@
{
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
- "version": "10.25.0",
+ "version": "10.26.0",
"npmClient": "yarn"
}
diff --git a/packages/angular/package.json b/packages/angular/package.json
index 6102320de760..01912cb13f79 100644
--- a/packages/angular/package.json
+++ b/packages/angular/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry/angular",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Official Sentry SDK for Angular",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/angular",
@@ -21,8 +21,8 @@
"rxjs": "^6.5.5 || ^7.x"
},
"dependencies": {
- "@sentry/browser": "10.25.0",
- "@sentry/core": "10.25.0",
+ "@sentry/browser": "10.26.0",
+ "@sentry/core": "10.26.0",
"tslib": "^2.4.1"
},
"devDependencies": {
diff --git a/packages/astro/package.json b/packages/astro/package.json
index c8ff489ca77b..32a2cf0e3833 100644
--- a/packages/astro/package.json
+++ b/packages/astro/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry/astro",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Official Sentry SDK for Astro",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/astro",
@@ -56,9 +56,9 @@
"astro": ">=3.x || >=4.0.0-beta || >=5.x"
},
"dependencies": {
- "@sentry/browser": "10.25.0",
- "@sentry/core": "10.25.0",
- "@sentry/node": "10.25.0",
+ "@sentry/browser": "10.26.0",
+ "@sentry/core": "10.26.0",
+ "@sentry/node": "10.26.0",
"@sentry/vite-plugin": "^4.1.0"
},
"devDependencies": {
diff --git a/packages/aws-serverless/package.json b/packages/aws-serverless/package.json
index 7ee6a0a50d97..cd0ad16d9e7c 100644
--- a/packages/aws-serverless/package.json
+++ b/packages/aws-serverless/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry/aws-serverless",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Official Sentry SDK for AWS Lambda and AWS Serverless Environments",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/aws-serverless",
@@ -69,9 +69,9 @@
"@opentelemetry/instrumentation": "^0.204.0",
"@opentelemetry/instrumentation-aws-sdk": "0.59.0",
"@opentelemetry/semantic-conventions": "^1.37.0",
- "@sentry/core": "10.25.0",
- "@sentry/node": "10.25.0",
- "@sentry/node-core": "10.25.0",
+ "@sentry/core": "10.26.0",
+ "@sentry/node": "10.26.0",
+ "@sentry/node-core": "10.26.0",
"@types/aws-lambda": "^8.10.62"
},
"devDependencies": {
diff --git a/packages/aws-serverless/src/init.ts b/packages/aws-serverless/src/init.ts
index 25180a41f6e6..29ec1a16262a 100644
--- a/packages/aws-serverless/src/init.ts
+++ b/packages/aws-serverless/src/init.ts
@@ -1,8 +1,7 @@
import type { Integration, Options } from '@sentry/core';
-import { applySdkMetadata, debug, getSDKSource } from '@sentry/core';
+import { applySdkMetadata, debug, envToBool, getSDKSource } from '@sentry/core';
import type { NodeClient, NodeOptions } from '@sentry/node';
import { getDefaultIntegrationsWithoutPerformance, initWithoutDefaultIntegrations } from '@sentry/node';
-import { envToBool } from '@sentry/node-core';
import { DEBUG_BUILD } from './debug-build';
import { awsIntegration } from './integration/aws';
import { awsLambdaIntegration } from './integration/awslambda';
diff --git a/packages/browser-utils/package.json b/packages/browser-utils/package.json
index 338175ef5ad5..117fec1f473c 100644
--- a/packages/browser-utils/package.json
+++ b/packages/browser-utils/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry-internal/browser-utils",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Browser Utilities for all Sentry JavaScript SDKs",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/browser-utils",
@@ -39,7 +39,7 @@
"access": "public"
},
"dependencies": {
- "@sentry/core": "10.25.0"
+ "@sentry/core": "10.26.0"
},
"scripts": {
"build": "run-p build:transpile build:types",
diff --git a/packages/browser/package.json b/packages/browser/package.json
index 555062e2744f..c7b21beb6766 100644
--- a/packages/browser/package.json
+++ b/packages/browser/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry/browser",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Official Sentry SDK for browsers",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/browser",
@@ -44,14 +44,14 @@
"access": "public"
},
"dependencies": {
- "@sentry-internal/browser-utils": "10.25.0",
- "@sentry-internal/feedback": "10.25.0",
- "@sentry-internal/replay": "10.25.0",
- "@sentry-internal/replay-canvas": "10.25.0",
- "@sentry/core": "10.25.0"
+ "@sentry-internal/browser-utils": "10.26.0",
+ "@sentry-internal/feedback": "10.26.0",
+ "@sentry-internal/replay": "10.26.0",
+ "@sentry-internal/replay-canvas": "10.26.0",
+ "@sentry/core": "10.26.0"
},
"devDependencies": {
- "@sentry-internal/integration-shims": "10.25.0",
+ "@sentry-internal/integration-shims": "10.26.0",
"fake-indexeddb": "^6.2.4"
},
"scripts": {
diff --git a/packages/browser/src/client.ts b/packages/browser/src/client.ts
index ea55174f340c..554d3dd2d6b5 100644
--- a/packages/browser/src/client.ts
+++ b/packages/browser/src/client.ts
@@ -70,9 +70,29 @@ type BrowserSpecificOptions = BrowserClientReplayOptions &
*
* Either set it to true, or provide a specific Spotlight Sidecar URL.
*
+ * Alternatively, you can configure Spotlight using environment variables (checked in this order):
+ * - PUBLIC_SENTRY_SPOTLIGHT (SvelteKit, Astro, Qwik)
+ * - NEXT_PUBLIC_SENTRY_SPOTLIGHT (Next.js)
+ * - VITE_SENTRY_SPOTLIGHT (Vite)
+ * - NUXT_PUBLIC_SENTRY_SPOTLIGHT (Nuxt)
+ * - REACT_APP_SENTRY_SPOTLIGHT (Create React App)
+ * - VUE_APP_SENTRY_SPOTLIGHT (Vue CLI)
+ * - GATSBY_SENTRY_SPOTLIGHT (Gatsby)
+ * - SENTRY_SPOTLIGHT (fallback for non-framework setups)
+ *
+ * Framework-specific vars have higher priority to support Docker Compose setups where
+ * backend uses SENTRY_SPOTLIGHT with Docker hostnames while frontend needs localhost.
+ *
+ * Precedence rules:
+ * - If this option is `false`, Spotlight is disabled (env vars ignored)
+ * - If this option is a string URL, that URL is used (env vars ignored)
+ * - If this option is `true` and env var is a URL, the env var URL is used
+ * - If this option is `undefined`, the env var value is used (if set)
+ *
* More details: https://spotlightjs.com/
*
* IMPORTANT: Only set this option to `true` while developing, not in production!
+ * Spotlight is automatically excluded from production bundles.
*/
spotlight?: boolean | string;
};
diff --git a/packages/browser/src/sdk.ts b/packages/browser/src/sdk.ts
index 800c1b701352..11a8ccf19548 100644
--- a/packages/browser/src/sdk.ts
+++ b/packages/browser/src/sdk.ts
@@ -5,6 +5,7 @@ import {
getIntegrationsToSetup,
inboundFiltersIntegration,
initAndBind,
+ resolveSpotlightOptions,
stackParserFromStackParserOptions,
} from '@sentry/core';
import type { BrowserClientOptions, BrowserOptions } from './client';
@@ -19,6 +20,7 @@ import { spotlightBrowserIntegration } from './integrations/spotlight';
import { defaultStackParser } from './stack-parsers';
import { makeFetchTransport } from './transports/fetch';
import { checkAndWarnIfIsEmbeddedBrowserExtension } from './utils/detectBrowserExtension';
+import { getSpotlightConfig } from './utils/spotlightConfig';
/** Get the default integrations for the browser SDK. */
export function getDefaultIntegrations(_options: Options): Integration[] {
@@ -95,11 +97,16 @@ export function init(options: BrowserOptions = {}): Client | undefined {
options.defaultIntegrations == null ? getDefaultIntegrations(options) : options.defaultIntegrations;
/* rollup-include-development-only */
- if (options.spotlight) {
+ // Resolve Spotlight configuration with proper precedence
+ const envSpotlight = getSpotlightConfig();
+ // resolveSpotlightOptions is the single source of truth that ensures empty strings are never used
+ const spotlightValue = resolveSpotlightOptions(options.spotlight, envSpotlight);
+
+ if (spotlightValue) {
if (!defaultIntegrations) {
defaultIntegrations = [];
}
- const args = typeof options.spotlight === 'string' ? { sidecarUrl: options.spotlight } : undefined;
+ const args = typeof spotlightValue === 'string' ? { sidecarUrl: spotlightValue } : undefined;
defaultIntegrations.push(spotlightBrowserIntegration(args));
}
/* rollup-include-development-only-end */
diff --git a/packages/browser/src/utils/env.ts b/packages/browser/src/utils/env.ts
new file mode 100644
index 000000000000..94fb211fc644
--- /dev/null
+++ b/packages/browser/src/utils/env.ts
@@ -0,0 +1,39 @@
+/**
+ * Safely gets an environment variable value with defensive guards for browser environments.
+ * Checks both process.env and import.meta.env to support different bundlers:
+ * - process.env: Webpack, Next.js, Create React App, Parcel
+ * - import.meta.env: Vite, Astro, SvelteKit
+ *
+ * @param key - The environment variable key to look up
+ * @returns The value of the environment variable or undefined if not found
+ */
+export function getEnvValue(key: string): string | undefined {
+ // Check process.env first (Webpack, Next.js, CRA, etc.)
+ try {
+ if (typeof process !== 'undefined' && process.env) {
+ const value = process.env[key];
+ if (value !== undefined) {
+ return value;
+ }
+ }
+ } catch (e) {
+ // Silently ignore - process might not be accessible or might throw in some environments
+ }
+
+ // Check import.meta.env (Vite, Astro, SvelteKit, etc.)
+ try {
+ // @ts-expect-error import.meta.env might not exist in all environments
+ if (typeof import.meta !== 'undefined' && import.meta.env) {
+ // @ts-expect-error import.meta.env is typed differently in different environments
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
+ const value = import.meta.env[key];
+ if (value !== undefined) {
+ return value;
+ }
+ }
+ } catch (e) {
+ // Silently ignore - import.meta.env might not be accessible or might throw
+ }
+
+ return undefined;
+}
diff --git a/packages/browser/src/utils/spotlightConfig.ts b/packages/browser/src/utils/spotlightConfig.ts
new file mode 100644
index 000000000000..0fd855c6cc6b
--- /dev/null
+++ b/packages/browser/src/utils/spotlightConfig.ts
@@ -0,0 +1,66 @@
+import { debug, envToBool } from '@sentry/core';
+import { DEBUG_BUILD } from '../debug-build';
+import { getEnvValue } from './env';
+
+/**
+ * Environment variable keys to check for Spotlight configuration, in priority order.
+ * The first one found with a value will be used.
+ *
+ * IMPORTANT: Framework-specific variables (PUBLIC_*, NEXT_PUBLIC_*, etc.) are prioritized
+ * over the generic SENTRY_SPOTLIGHT to support Docker Compose setups where:
+ * - Backend services need SENTRY_SPOTLIGHT=http://host.internal.docker:8969/stream
+ * - Frontend code needs localhost (via framework-specific vars like NEXT_PUBLIC_SENTRY_SPOTLIGHT=http://localhost:8969/stream)
+ *
+ * SENTRY_SPOTLIGHT is kept as a fallback for:
+ * - Simple non-Docker setups
+ * - Remote Spotlight instances when no framework-specific var is set
+ */
+const SPOTLIGHT_ENV_KEYS = [
+ 'PUBLIC_SENTRY_SPOTLIGHT', // SvelteKit, Astro, Qwik
+ 'NEXT_PUBLIC_SENTRY_SPOTLIGHT', // Next.js
+ 'VITE_SENTRY_SPOTLIGHT', // Vite
+ 'NUXT_PUBLIC_SENTRY_SPOTLIGHT', // Nuxt
+ 'REACT_APP_SENTRY_SPOTLIGHT', // Create React App
+ 'VUE_APP_SENTRY_SPOTLIGHT', // Vue CLI
+ 'GATSBY_SENTRY_SPOTLIGHT', // Gatsby
+ 'SENTRY_SPOTLIGHT', // Fallback/base name - works in Parcel, Webpack, Rspack, Rollup, Rolldown, Node.js
+] as const;
+
+/**
+ * Gets the Spotlight configuration from environment variables.
+ * Checks multiple environment variable prefixes in priority order to support
+ * different bundlers and frameworks.
+ *
+ * @returns The resolved Spotlight configuration (boolean | string | undefined)
+ */
+export function getSpotlightConfig(): boolean | string | undefined {
+ for (const key of SPOTLIGHT_ENV_KEYS) {
+ const value = getEnvValue(key);
+
+ if (value !== undefined) {
+ // Try to parse as boolean first (strict mode)
+ const boolValue = envToBool(value, { strict: true });
+
+ if (boolValue !== null) {
+ // It's a valid boolean value
+ if (DEBUG_BUILD) {
+ debug.log(`[Spotlight] Found ${key}=${String(boolValue)} in environment variables`);
+ }
+ return boolValue;
+ }
+
+ // Not a boolean, treat as custom URL string
+ // Note: Empty/whitespace strings are intentionally returned as-is. The resolveSpotlightOptions
+ // function is the single source of truth for filtering these and ensuring empty strings are
+ // NEVER used (returns undefined instead).
+ if (DEBUG_BUILD) {
+ debug.log(`[Spotlight] Found ${key}=${value} (custom URL) in environment variables`);
+ }
+ return value;
+ }
+ }
+
+ // No Spotlight configuration found in environment
+ // Note: Implicit return of undefined saves bytes and is tree-shaken in production builds
+ return undefined;
+}
diff --git a/packages/browser/test/sdk.test.ts b/packages/browser/test/sdk.test.ts
index b7972797182f..893624560c24 100644
--- a/packages/browser/test/sdk.test.ts
+++ b/packages/browser/test/sdk.test.ts
@@ -234,6 +234,154 @@ describe('init', () => {
});
});
+ describe('Spotlight environment variable support', () => {
+ let originalProcess: typeof globalThis.process | undefined;
+
+ afterEach(() => {
+ if (originalProcess !== undefined) {
+ globalThis.process = originalProcess;
+ } else {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ delete (globalThis as any).process;
+ }
+ });
+
+ it('uses environment variable when options.spotlight is undefined', () => {
+ originalProcess = globalThis.process;
+ globalThis.process = {
+ env: {
+ SENTRY_SPOTLIGHT: 'true',
+ } as Record,
+ } as NodeJS.Process;
+
+ // @ts-expect-error this is fine for testing
+ const initAndBindSpy = vi.spyOn(SentryCore, 'initAndBind').mockImplementationOnce(() => {});
+ const options = getDefaultBrowserOptions({ dsn: PUBLIC_DSN, spotlight: undefined });
+ init(options);
+
+ const optionsPassed = initAndBindSpy.mock.calls[0]?.[1];
+ // Spotlight integration should be added
+ const spotlightIntegration = optionsPassed?.integrations.find((i: Integration) => i.name === 'SpotlightBrowser');
+ expect(spotlightIntegration).toBeDefined();
+ });
+
+ it('does not add Spotlight when environment variable is false', () => {
+ originalProcess = globalThis.process;
+ globalThis.process = {
+ env: {
+ SENTRY_SPOTLIGHT: 'false',
+ } as Record,
+ } as NodeJS.Process;
+
+ // @ts-expect-error this is fine for testing
+ const initAndBindSpy = vi.spyOn(SentryCore, 'initAndBind').mockImplementationOnce(() => {});
+ const options = getDefaultBrowserOptions({ dsn: PUBLIC_DSN, spotlight: undefined });
+ init(options);
+
+ const optionsPassed = initAndBindSpy.mock.calls[0]?.[1];
+ // Spotlight integration should NOT be added
+ const spotlightIntegration = optionsPassed?.integrations.find((i: Integration) => i.name === 'SpotlightBrowser');
+ expect(spotlightIntegration).toBeUndefined();
+ });
+
+ it('options.spotlight=false takes precedence over environment variable', () => {
+ originalProcess = globalThis.process;
+ globalThis.process = {
+ env: {
+ SENTRY_SPOTLIGHT: 'true',
+ } as Record,
+ } as NodeJS.Process;
+
+ // @ts-expect-error this is fine for testing
+ const initAndBindSpy = vi.spyOn(SentryCore, 'initAndBind').mockImplementationOnce(() => {});
+ const options = getDefaultBrowserOptions({ dsn: PUBLIC_DSN, spotlight: false });
+ init(options);
+
+ const optionsPassed = initAndBindSpy.mock.calls[0]?.[1];
+ // Spotlight integration should NOT be added even though env var is true
+ const spotlightIntegration = optionsPassed?.integrations.find((i: Integration) => i.name === 'SpotlightBrowser');
+ expect(spotlightIntegration).toBeUndefined();
+ });
+
+ it('options.spotlight=url takes precedence over environment variable', () => {
+ originalProcess = globalThis.process;
+ const customUrl = 'http://custom:1234/stream';
+ globalThis.process = {
+ env: {
+ SENTRY_SPOTLIGHT: 'http://env:5678/stream',
+ } as Record,
+ } as NodeJS.Process;
+
+ // @ts-expect-error this is fine for testing
+ const initAndBindSpy = vi.spyOn(SentryCore, 'initAndBind').mockImplementationOnce(() => {});
+ const options = getDefaultBrowserOptions({ dsn: PUBLIC_DSN, spotlight: customUrl });
+ init(options);
+
+ const optionsPassed = initAndBindSpy.mock.calls[0]?.[1];
+ // Spotlight integration should be added (we can't easily check the URL here without deeper inspection)
+ const spotlightIntegration = optionsPassed?.integrations.find((i: Integration) => i.name === 'SpotlightBrowser');
+ expect(spotlightIntegration).toBeDefined();
+ });
+
+ it('uses environment variable URL when options.spotlight=true', () => {
+ originalProcess = globalThis.process;
+ globalThis.process = {
+ env: {
+ SENTRY_SPOTLIGHT: 'http://env:5678/stream',
+ } as Record,
+ } as NodeJS.Process;
+
+ // @ts-expect-error this is fine for testing
+ const initAndBindSpy = vi.spyOn(SentryCore, 'initAndBind').mockImplementationOnce(() => {});
+ const options = getDefaultBrowserOptions({ dsn: PUBLIC_DSN, spotlight: true });
+ init(options);
+
+ const optionsPassed = initAndBindSpy.mock.calls[0]?.[1];
+ // Spotlight integration should be added
+ const spotlightIntegration = optionsPassed?.integrations.find((i: Integration) => i.name === 'SpotlightBrowser');
+ expect(spotlightIntegration).toBeDefined();
+ });
+
+ it('respects priority order: PUBLIC_SENTRY_SPOTLIGHT over SENTRY_SPOTLIGHT', () => {
+ originalProcess = globalThis.process;
+ globalThis.process = {
+ env: {
+ PUBLIC_SENTRY_SPOTLIGHT: 'true',
+ SENTRY_SPOTLIGHT: 'false',
+ } as Record,
+ } as NodeJS.Process;
+
+ // @ts-expect-error this is fine for testing
+ const initAndBindSpy = vi.spyOn(SentryCore, 'initAndBind').mockImplementationOnce(() => {});
+ const options = getDefaultBrowserOptions({ dsn: PUBLIC_DSN, spotlight: undefined });
+ init(options);
+
+ const optionsPassed = initAndBindSpy.mock.calls[0]?.[1];
+ // Spotlight integration should be added (PUBLIC_SENTRY_SPOTLIGHT=true wins)
+ const spotlightIntegration = optionsPassed?.integrations.find((i: Integration) => i.name === 'SpotlightBrowser');
+ expect(spotlightIntegration).toBeDefined();
+ });
+
+ it('uses framework-specific prefix when base is not set', () => {
+ originalProcess = globalThis.process;
+ globalThis.process = {
+ env: {
+ NEXT_PUBLIC_SENTRY_SPOTLIGHT: 'true',
+ } as Record,
+ } as NodeJS.Process;
+
+ // @ts-expect-error this is fine for testing
+ const initAndBindSpy = vi.spyOn(SentryCore, 'initAndBind').mockImplementationOnce(() => {});
+ const options = getDefaultBrowserOptions({ dsn: PUBLIC_DSN, spotlight: undefined });
+ init(options);
+
+ const optionsPassed = initAndBindSpy.mock.calls[0]?.[1];
+ // Spotlight integration should be added
+ const spotlightIntegration = optionsPassed?.integrations.find((i: Integration) => i.name === 'SpotlightBrowser');
+ expect(spotlightIntegration).toBeDefined();
+ });
+ });
+
it('returns a client from init', () => {
const client = init();
expect(client).not.toBeUndefined();
diff --git a/packages/browser/test/utils/env.test.ts b/packages/browser/test/utils/env.test.ts
new file mode 100644
index 000000000000..6c88985da904
--- /dev/null
+++ b/packages/browser/test/utils/env.test.ts
@@ -0,0 +1,90 @@
+/**
+ * @vitest-environment jsdom
+ */
+
+import { afterEach, beforeEach, describe, expect, it } from 'vitest';
+import { getEnvValue } from '../../src/utils/env';
+
+describe('getEnvValue', () => {
+ let originalProcess: typeof globalThis.process | undefined;
+
+ beforeEach(() => {
+ // Store original values
+ originalProcess = globalThis.process;
+ });
+
+ afterEach(() => {
+ // Restore original values
+ if (originalProcess !== undefined) {
+ globalThis.process = originalProcess;
+ } else {
+ delete (globalThis as any).process;
+ }
+ });
+
+ it('returns value from process.env when available', () => {
+ globalThis.process = {
+ env: {
+ TEST_VAR: 'test-value',
+ },
+ } as any;
+
+ expect(getEnvValue('TEST_VAR')).toBe('test-value');
+ });
+
+ it('returns undefined when process.env does not exist', () => {
+ delete (globalThis as any).process;
+
+ expect(getEnvValue('NONEXISTENT')).toBeUndefined();
+ });
+
+ it('returns undefined when variable does not exist in process.env', () => {
+ globalThis.process = {
+ env: {},
+ } as any;
+
+ expect(getEnvValue('NONEXISTENT')).toBeUndefined();
+ });
+
+ it('handles missing process object gracefully', () => {
+ delete (globalThis as any).process;
+
+ expect(() => getEnvValue('TEST_VAR')).not.toThrow();
+ expect(getEnvValue('TEST_VAR')).toBeUndefined();
+ });
+
+ it('handles missing process.env gracefully', () => {
+ globalThis.process = {} as any;
+
+ expect(() => getEnvValue('TEST_VAR')).not.toThrow();
+ expect(getEnvValue('TEST_VAR')).toBeUndefined();
+ });
+
+ it('handles process.env access throwing an error', () => {
+ globalThis.process = {
+ get env() {
+ throw new Error('Access denied');
+ },
+ } as any;
+
+ expect(() => getEnvValue('TEST_VAR')).not.toThrow();
+ expect(getEnvValue('TEST_VAR')).toBeUndefined();
+ });
+
+ it('returns empty string when value is empty string in process.env', () => {
+ globalThis.process = {
+ env: {
+ EMPTY_VAR: '',
+ },
+ } as any;
+
+ expect(getEnvValue('EMPTY_VAR')).toBe('');
+ });
+
+ // Note: import.meta.env support cannot be easily unit tested because import.meta
+ // is a read-only compile-time construct that cannot be mocked. The import.meta.env
+ // functionality is tested via e2e tests with real Vite-based frameworks (Vue, Astro, etc.)
+ //
+ // The implementation safely checks for import.meta.env existence and will use it
+ // when available in Vite/Astro/SvelteKit builds.
+});
diff --git a/packages/browser/test/utils/spotlightConfig.test.ts b/packages/browser/test/utils/spotlightConfig.test.ts
new file mode 100644
index 000000000000..a540c6be8ce6
--- /dev/null
+++ b/packages/browser/test/utils/spotlightConfig.test.ts
@@ -0,0 +1,268 @@
+/**
+ * @vitest-environment jsdom
+ */
+
+import { afterEach, beforeEach, describe, expect, it } from 'vitest';
+import { getSpotlightConfig } from '../../src/utils/spotlightConfig';
+
+describe('getSpotlightConfig', () => {
+ let originalProcess: typeof globalThis.process | undefined;
+
+ beforeEach(() => {
+ originalProcess = globalThis.process;
+ });
+
+ afterEach(() => {
+ if (originalProcess !== undefined) {
+ globalThis.process = originalProcess;
+ } else {
+ delete (globalThis as typeof globalThis & { process?: NodeJS.Process }).process;
+ }
+ });
+
+ it('returns undefined when no environment variables are set', () => {
+ globalThis.process = {
+ env: {},
+ } as NodeJS.Process;
+
+ expect(getSpotlightConfig()).toBeUndefined();
+ });
+
+ it('returns boolean true when SENTRY_SPOTLIGHT=true', () => {
+ globalThis.process = {
+ env: {
+ SENTRY_SPOTLIGHT: 'true',
+ } as Record,
+ } as NodeJS.Process;
+
+ expect(getSpotlightConfig()).toBe(true);
+ });
+
+ it('returns boolean false when SENTRY_SPOTLIGHT=false', () => {
+ globalThis.process = {
+ env: {
+ SENTRY_SPOTLIGHT: 'false',
+ } as Record,
+ } as NodeJS.Process;
+
+ expect(getSpotlightConfig()).toBe(false);
+ });
+
+ it('returns URL string when SENTRY_SPOTLIGHT is a URL', () => {
+ const customUrl = 'http://localhost:9999/stream';
+ globalThis.process = {
+ env: {
+ SENTRY_SPOTLIGHT: customUrl,
+ } as Record,
+ } as NodeJS.Process;
+
+ expect(getSpotlightConfig()).toBe(customUrl);
+ });
+
+ it('returns empty string when SENTRY_SPOTLIGHT is an empty string (filtered by resolveSpotlightOptions)', () => {
+ globalThis.process = {
+ env: {
+ SENTRY_SPOTLIGHT: '',
+ } as Record,
+ } as NodeJS.Process;
+
+ expect(getSpotlightConfig()).toBe('');
+ });
+
+ it('returns whitespace string when SENTRY_SPOTLIGHT is whitespace only (filtered by resolveSpotlightOptions)', () => {
+ globalThis.process = {
+ env: {
+ SENTRY_SPOTLIGHT: ' ',
+ } as Record,
+ } as NodeJS.Process;
+
+ expect(getSpotlightConfig()).toBe(' ');
+ });
+
+ it('parses various truthy values correctly', () => {
+ const truthyValues = ['true', '1', 'yes', 'on', 't', 'y', 'TRUE', 'YES'];
+
+ truthyValues.forEach(value => {
+ globalThis.process = {
+ env: {
+ SENTRY_SPOTLIGHT: value,
+ } as Record,
+ } as NodeJS.Process;
+
+ expect(getSpotlightConfig()).toBe(true);
+ });
+ });
+
+ it('parses various falsy values correctly', () => {
+ const falsyValues = ['false', '0', 'no', 'off', 'f', 'n', 'FALSE', 'NO'];
+
+ falsyValues.forEach(value => {
+ globalThis.process = {
+ env: {
+ SENTRY_SPOTLIGHT: value,
+ } as Record,
+ } as NodeJS.Process;
+
+ expect(getSpotlightConfig()).toBe(false);
+ });
+ });
+
+ describe('priority order', () => {
+ it('prioritizes PUBLIC_SENTRY_SPOTLIGHT over SENTRY_SPOTLIGHT', () => {
+ globalThis.process = {
+ env: {
+ PUBLIC_SENTRY_SPOTLIGHT: 'true',
+ SENTRY_SPOTLIGHT: 'false',
+ } as Record,
+ } as NodeJS.Process;
+
+ expect(getSpotlightConfig()).toBe(true);
+ });
+
+ it('prioritizes PUBLIC_SENTRY_SPOTLIGHT when SENTRY_SPOTLIGHT is not set', () => {
+ globalThis.process = {
+ env: {
+ PUBLIC_SENTRY_SPOTLIGHT: 'true',
+ NEXT_PUBLIC_SENTRY_SPOTLIGHT: 'false',
+ } as Record,
+ } as NodeJS.Process;
+
+ expect(getSpotlightConfig()).toBe(true);
+ });
+
+ it('prioritizes NEXT_PUBLIC_SENTRY_SPOTLIGHT when higher priority vars not set', () => {
+ globalThis.process = {
+ env: {
+ NEXT_PUBLIC_SENTRY_SPOTLIGHT: 'true',
+ VITE_SENTRY_SPOTLIGHT: 'false',
+ } as Record,
+ } as NodeJS.Process;
+
+ expect(getSpotlightConfig()).toBe(true);
+ });
+
+ it('prioritizes VITE_SENTRY_SPOTLIGHT when higher priority vars not set', () => {
+ globalThis.process = {
+ env: {
+ VITE_SENTRY_SPOTLIGHT: 'true',
+ NUXT_PUBLIC_SENTRY_SPOTLIGHT: 'false',
+ } as Record,
+ } as NodeJS.Process;
+
+ expect(getSpotlightConfig()).toBe(true);
+ });
+
+ it('prioritizes NUXT_PUBLIC_SENTRY_SPOTLIGHT when higher priority vars not set', () => {
+ globalThis.process = {
+ env: {
+ NUXT_PUBLIC_SENTRY_SPOTLIGHT: 'true',
+ REACT_APP_SENTRY_SPOTLIGHT: 'false',
+ } as Record,
+ } as NodeJS.Process;
+
+ expect(getSpotlightConfig()).toBe(true);
+ });
+
+ it('uses REACT_APP_SENTRY_SPOTLIGHT when higher priority vars not set', () => {
+ globalThis.process = {
+ env: {
+ REACT_APP_SENTRY_SPOTLIGHT: 'true',
+ VUE_APP_SENTRY_SPOTLIGHT: 'false',
+ } as Record,
+ } as NodeJS.Process;
+
+ expect(getSpotlightConfig()).toBe(true);
+ });
+
+ it('uses VUE_APP_SENTRY_SPOTLIGHT when higher priority vars not set', () => {
+ globalThis.process = {
+ env: {
+ VUE_APP_SENTRY_SPOTLIGHT: 'true',
+ GATSBY_SENTRY_SPOTLIGHT: 'false',
+ } as Record,
+ } as NodeJS.Process;
+
+ expect(getSpotlightConfig()).toBe(true);
+ });
+
+ it('uses GATSBY_SENTRY_SPOTLIGHT when all higher priority vars not set', () => {
+ globalThis.process = {
+ env: {
+ GATSBY_SENTRY_SPOTLIGHT: 'true',
+ SENTRY_SPOTLIGHT: 'false',
+ } as Record,
+ } as NodeJS.Process;
+
+ expect(getSpotlightConfig()).toBe(true);
+ });
+
+ it('uses SENTRY_SPOTLIGHT as fallback when no framework-specific vars are set', () => {
+ globalThis.process = {
+ env: {
+ SENTRY_SPOTLIGHT: 'true',
+ } as Record,
+ } as NodeJS.Process;
+
+ expect(getSpotlightConfig()).toBe(true);
+ });
+
+ it('returns first found value in priority order with URLs', () => {
+ const highPriorityUrl = 'http://high-priority:8969/stream';
+ const lowPriorityUrl = 'http://low-priority:8969/stream';
+
+ globalThis.process = {
+ env: {
+ PUBLIC_SENTRY_SPOTLIGHT: highPriorityUrl,
+ GATSBY_SENTRY_SPOTLIGHT: lowPriorityUrl,
+ } as Record,
+ } as NodeJS.Process;
+
+ expect(getSpotlightConfig()).toBe(highPriorityUrl);
+ });
+
+ it('prioritizes framework-specific URL over SENTRY_SPOTLIGHT URL (Docker Compose scenario)', () => {
+ // Simulates Docker Compose setup where:
+ // - SENTRY_SPOTLIGHT is set for backend services with Docker hostname
+ // - Framework-specific var is set for frontend with localhost
+ const dockerHostUrl = 'http://host.docker.internal:8969/stream';
+ const localhostUrl = 'http://localhost:8969/stream';
+
+ globalThis.process = {
+ env: {
+ NEXT_PUBLIC_SENTRY_SPOTLIGHT: localhostUrl,
+ SENTRY_SPOTLIGHT: dockerHostUrl,
+ } as Record,
+ } as NodeJS.Process;
+
+ // Framework-specific var should be used, not SENTRY_SPOTLIGHT
+ expect(getSpotlightConfig()).toBe(localhostUrl);
+ });
+
+ it('uses SENTRY_SPOTLIGHT URL when no framework-specific vars are set (remote Spotlight)', () => {
+ const remoteUrl = 'http://remote-spotlight.example.com:8969/stream';
+
+ globalThis.process = {
+ env: {
+ SENTRY_SPOTLIGHT: remoteUrl,
+ } as Record,
+ } as NodeJS.Process;
+
+ // Should use SENTRY_SPOTLIGHT as fallback
+ expect(getSpotlightConfig()).toBe(remoteUrl);
+ });
+ });
+
+ it('handles missing process object gracefully', () => {
+ delete (globalThis as typeof globalThis & { process?: NodeJS.Process }).process;
+
+ expect(() => getSpotlightConfig()).not.toThrow();
+ expect(getSpotlightConfig()).toBeUndefined();
+ });
+
+ it('handles missing process.env gracefully', () => {
+ globalThis.process = {} as NodeJS.Process;
+
+ expect(() => getSpotlightConfig()).not.toThrow();
+ expect(getSpotlightConfig()).toBeUndefined();
+ });
+});
diff --git a/packages/bun/package.json b/packages/bun/package.json
index 288e327bf6eb..fcd538862c17 100644
--- a/packages/bun/package.json
+++ b/packages/bun/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry/bun",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Official Sentry SDK for bun",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/bun",
@@ -39,8 +39,8 @@
"access": "public"
},
"dependencies": {
- "@sentry/core": "10.25.0",
- "@sentry/node": "10.25.0"
+ "@sentry/core": "10.26.0",
+ "@sentry/node": "10.26.0"
},
"devDependencies": {
"bun-types": "^1.2.9"
diff --git a/packages/cloudflare/package.json b/packages/cloudflare/package.json
index a620dc84b3d9..ee8cba264e5f 100644
--- a/packages/cloudflare/package.json
+++ b/packages/cloudflare/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry/cloudflare",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Official Sentry SDK for Cloudflare Workers and Pages",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/cloudflare",
@@ -50,7 +50,7 @@
},
"dependencies": {
"@opentelemetry/api": "^1.9.0",
- "@sentry/core": "10.25.0"
+ "@sentry/core": "10.26.0"
},
"peerDependencies": {
"@cloudflare/workers-types": "^4.x"
diff --git a/packages/core/package.json b/packages/core/package.json
index e45152996f0f..8ffc256e2f26 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry/core",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Base implementation for all Sentry JavaScript SDKs",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/core",
diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts
index 014a411d0265..d3f36551f94e 100644
--- a/packages/core/src/index.ts
+++ b/packages/core/src/index.ts
@@ -272,6 +272,9 @@ export {
} from './utils/tracing';
export { getSDKSource, isBrowserBundle } from './utils/env';
export type { SdkSource } from './utils/env';
+export { envToBool } from './utils/envToBool';
+export type { BoolCastOptions, StrictBoolCast, LooseBoolCast } from './utils/envToBool';
+export { resolveSpotlightOptions } from './utils/resolveSpotlightOptions';
export {
addItemToEnvelope,
createAttachmentEnvelopeItem,
diff --git a/packages/node-core/src/utils/envToBool.ts b/packages/core/src/utils/envToBool.ts
similarity index 100%
rename from packages/node-core/src/utils/envToBool.ts
rename to packages/core/src/utils/envToBool.ts
diff --git a/packages/core/src/utils/resolveSpotlightOptions.ts b/packages/core/src/utils/resolveSpotlightOptions.ts
new file mode 100644
index 000000000000..520b1f4d6647
--- /dev/null
+++ b/packages/core/src/utils/resolveSpotlightOptions.ts
@@ -0,0 +1,36 @@
+/**
+ * Resolves the final spotlight configuration based on options and environment variables.
+ * Implements the precedence rules from the Spotlight spec.
+ *
+ * This is the single source of truth for filtering empty/whitespace strings - it ensures that
+ * empty strings are NEVER returned (returns undefined instead). All callers can rely on this
+ * guarantee when handling spotlight configuration.
+ *
+ * @param optionsSpotlight - The spotlight option from user config (false | true | string | undefined)
+ * @param envSpotlight - The spotlight value from environment variables (false | true | string | undefined)
+ * @returns The resolved spotlight configuration (false | true | string | undefined) - NEVER an empty string
+ */
+export function resolveSpotlightOptions(
+ optionsSpotlight: boolean | string | undefined,
+ envSpotlight: boolean | string | undefined,
+): boolean | string | undefined {
+ if (optionsSpotlight === false) {
+ // Explicitly disabled - ignore env vars
+ return false;
+ }
+
+ if (typeof optionsSpotlight === 'string') {
+ // Custom URL provided - ignore env vars
+ // Treat empty strings as undefined to prevent invalid URL connections
+ return optionsSpotlight.trim() === '' ? undefined : optionsSpotlight;
+ }
+
+ // optionsSpotlight is true or undefined
+ const envBool = typeof envSpotlight === 'boolean' ? envSpotlight : undefined;
+ // Treat empty/whitespace-only strings as undefined to prevent invalid URL connections
+ const envUrl = typeof envSpotlight === 'string' && envSpotlight.trim() !== '' ? envSpotlight : undefined;
+
+ return optionsSpotlight === true
+ ? (envUrl ?? true) // true: use env URL if present, otherwise true
+ : (envBool ?? envUrl); // undefined: use env var (bool or URL)
+}
diff --git a/packages/node-core/test/utils/envToBool.test.ts b/packages/core/test/utils/envToBool.test.ts
similarity index 100%
rename from packages/node-core/test/utils/envToBool.test.ts
rename to packages/core/test/utils/envToBool.test.ts
diff --git a/packages/core/test/utils/resolveSpotlightOptions.test.ts b/packages/core/test/utils/resolveSpotlightOptions.test.ts
new file mode 100644
index 000000000000..27b1a61dddd5
--- /dev/null
+++ b/packages/core/test/utils/resolveSpotlightOptions.test.ts
@@ -0,0 +1,120 @@
+import { describe, expect, it } from 'vitest';
+import { resolveSpotlightOptions } from '../../src/utils/resolveSpotlightOptions';
+
+describe('resolveSpotlightOptions', () => {
+ it('returns false when options.spotlight === false, regardless of env', () => {
+ expect(resolveSpotlightOptions(false, undefined)).toBe(false);
+ expect(resolveSpotlightOptions(false, true)).toBe(false);
+ expect(resolveSpotlightOptions(false, false)).toBe(false);
+ expect(resolveSpotlightOptions(false, 'http://localhost:8969')).toBe(false);
+ });
+
+ it('returns custom URL when options.spotlight is a string, regardless of env', () => {
+ const customUrl = 'http://custom:1234/stream';
+ expect(resolveSpotlightOptions(customUrl, undefined)).toBe(customUrl);
+ expect(resolveSpotlightOptions(customUrl, true)).toBe(customUrl);
+ expect(resolveSpotlightOptions(customUrl, false)).toBe(customUrl);
+ expect(resolveSpotlightOptions(customUrl, 'http://other:5678')).toBe(customUrl);
+ });
+
+ it('returns env URL when options.spotlight === true and env is a URL', () => {
+ const envUrl = 'http://localhost:8969/stream';
+ expect(resolveSpotlightOptions(true, envUrl)).toBe(envUrl);
+ });
+
+ it('returns true when options.spotlight === true and env is true', () => {
+ expect(resolveSpotlightOptions(true, true)).toBe(true);
+ });
+
+ it('returns true when options.spotlight === true and env is false', () => {
+ expect(resolveSpotlightOptions(true, false)).toBe(true);
+ });
+
+ it('returns true when options.spotlight === true and env is undefined', () => {
+ expect(resolveSpotlightOptions(true, undefined)).toBe(true);
+ });
+
+ it('returns env boolean when options.spotlight === undefined and env is boolean', () => {
+ expect(resolveSpotlightOptions(undefined, true)).toBe(true);
+ expect(resolveSpotlightOptions(undefined, false)).toBe(false);
+ });
+
+ it('returns env URL when options.spotlight === undefined and env is a URL', () => {
+ const envUrl = 'http://localhost:8969/stream';
+ expect(resolveSpotlightOptions(undefined, envUrl)).toBe(envUrl);
+ });
+
+ it('returns undefined when both options.spotlight and env are undefined', () => {
+ expect(resolveSpotlightOptions(undefined, undefined)).toBe(undefined);
+ });
+
+ it('prioritizes env URL over env boolean when options.spotlight === undefined', () => {
+ // This shouldn't happen in practice, but tests the logic path
+ // In reality, envSpotlight will be either boolean, string, or undefined
+ const envUrl = 'http://localhost:8969/stream';
+ expect(resolveSpotlightOptions(undefined, envUrl)).toBe(envUrl);
+ });
+
+ describe('empty string handling - NEVER returns empty strings', () => {
+ it('returns undefined (never empty string) when options.spotlight is an empty string', () => {
+ expect(resolveSpotlightOptions('', undefined)).toBeUndefined();
+ expect(resolveSpotlightOptions('', true)).toBeUndefined();
+ expect(resolveSpotlightOptions('', 'http://env:8969')).toBeUndefined();
+ });
+
+ it('returns undefined (never empty string) when options.spotlight is whitespace only', () => {
+ expect(resolveSpotlightOptions(' ', undefined)).toBeUndefined();
+ expect(resolveSpotlightOptions('\t\n', true)).toBeUndefined();
+ });
+
+ it('returns undefined (never empty string) when env is an empty string and options.spotlight is undefined', () => {
+ expect(resolveSpotlightOptions(undefined, '')).toBeUndefined();
+ });
+
+ it('returns undefined (never empty string) when env is whitespace only and options.spotlight is undefined', () => {
+ expect(resolveSpotlightOptions(undefined, ' ')).toBeUndefined();
+ expect(resolveSpotlightOptions(undefined, '\t\n')).toBeUndefined();
+ });
+
+ it('returns true when options.spotlight is true and env is empty string (filters out empty env)', () => {
+ expect(resolveSpotlightOptions(true, '')).toBe(true);
+ expect(resolveSpotlightOptions(true, ' ')).toBe(true);
+ });
+
+ it('returns valid URL when options.spotlight is valid URL even if env is empty (filters out empty env)', () => {
+ const validUrl = 'http://localhost:8969/stream';
+ expect(resolveSpotlightOptions(validUrl, '')).toBe(validUrl);
+ expect(resolveSpotlightOptions(validUrl, ' ')).toBe(validUrl);
+ });
+
+ it('NEVER returns empty string - comprehensive check of all combinations', () => {
+ // Test all possible combinations to ensure empty strings are never returned
+ const emptyValues = ['', ' ', '\t\n', ' \t \n '];
+ const nonEmptyValues = [false, true, undefined, 'http://localhost:8969'];
+
+ // Empty options.spotlight with any env
+ for (const emptyOption of emptyValues) {
+ for (const env of [...emptyValues, ...nonEmptyValues]) {
+ const result = resolveSpotlightOptions(emptyOption, env);
+ expect(result).not.toBe('');
+ // Only test regex on strings
+ if (typeof result === 'string') {
+ expect(result).not.toMatch(/^\s+$/);
+ }
+ }
+ }
+
+ // Any options.spotlight with empty env
+ for (const option of [...emptyValues, ...nonEmptyValues]) {
+ for (const emptyEnv of emptyValues) {
+ const result = resolveSpotlightOptions(option, emptyEnv);
+ expect(result).not.toBe('');
+ // Only test regex on strings
+ if (typeof result === 'string') {
+ expect(result).not.toMatch(/^\s+$/);
+ }
+ }
+ }
+ });
+ });
+});
diff --git a/packages/deno/package.json b/packages/deno/package.json
index 814d76142cc3..04ac8f592fd1 100644
--- a/packages/deno/package.json
+++ b/packages/deno/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry/deno",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Official Sentry SDK for Deno",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/deno",
@@ -25,7 +25,7 @@
],
"dependencies": {
"@opentelemetry/api": "^1.9.0",
- "@sentry/core": "10.25.0"
+ "@sentry/core": "10.26.0"
},
"scripts": {
"deno-types": "node ./scripts/download-deno-types.mjs",
diff --git a/packages/ember/package.json b/packages/ember/package.json
index 333eda5345d5..69a111ab54a9 100644
--- a/packages/ember/package.json
+++ b/packages/ember/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry/ember",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Official Sentry SDK for Ember.js",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/ember",
@@ -32,8 +32,8 @@
"dependencies": {
"@babel/core": "^7.27.7",
"@embroider/macros": "^1.16.0",
- "@sentry/browser": "10.25.0",
- "@sentry/core": "10.25.0",
+ "@sentry/browser": "10.26.0",
+ "@sentry/core": "10.26.0",
"ember-auto-import": "^2.7.2",
"ember-cli-babel": "^8.2.0",
"ember-cli-htmlbars": "^6.1.1",
diff --git a/packages/eslint-config-sdk/package.json b/packages/eslint-config-sdk/package.json
index 63c6f926f934..d45a301e1590 100644
--- a/packages/eslint-config-sdk/package.json
+++ b/packages/eslint-config-sdk/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry-internal/eslint-config-sdk",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Official Sentry SDK eslint config",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/eslint-config-sdk",
@@ -22,8 +22,8 @@
"access": "public"
},
"dependencies": {
- "@sentry-internal/eslint-plugin-sdk": "10.25.0",
- "@sentry-internal/typescript": "10.25.0",
+ "@sentry-internal/eslint-plugin-sdk": "10.26.0",
+ "@sentry-internal/typescript": "10.26.0",
"@typescript-eslint/eslint-plugin": "^5.48.0",
"@typescript-eslint/parser": "^5.48.0",
"eslint-config-prettier": "^6.11.0",
diff --git a/packages/eslint-plugin-sdk/package.json b/packages/eslint-plugin-sdk/package.json
index f8d9f4c615ee..bad2ae248475 100644
--- a/packages/eslint-plugin-sdk/package.json
+++ b/packages/eslint-plugin-sdk/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry-internal/eslint-plugin-sdk",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Official Sentry SDK eslint plugin",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/eslint-plugin-sdk",
diff --git a/packages/feedback/package.json b/packages/feedback/package.json
index aa65e00d8ab5..7c9899ffd305 100644
--- a/packages/feedback/package.json
+++ b/packages/feedback/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry-internal/feedback",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Sentry SDK integration for user feedback",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/feedback",
@@ -39,7 +39,7 @@
"access": "public"
},
"dependencies": {
- "@sentry/core": "10.25.0"
+ "@sentry/core": "10.26.0"
},
"devDependencies": {
"preact": "^10.19.4"
diff --git a/packages/gatsby/package.json b/packages/gatsby/package.json
index 1da49b3a4dca..8236ee72e0e9 100644
--- a/packages/gatsby/package.json
+++ b/packages/gatsby/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry/gatsby",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Official Sentry SDK for Gatsby.js",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/gatsby",
@@ -45,8 +45,8 @@
"access": "public"
},
"dependencies": {
- "@sentry/core": "10.25.0",
- "@sentry/react": "10.25.0",
+ "@sentry/core": "10.26.0",
+ "@sentry/react": "10.26.0",
"@sentry/webpack-plugin": "^4.1.1"
},
"peerDependencies": {
diff --git a/packages/google-cloud-serverless/package.json b/packages/google-cloud-serverless/package.json
index c742b5a3a154..6afb10e14c42 100644
--- a/packages/google-cloud-serverless/package.json
+++ b/packages/google-cloud-serverless/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry/google-cloud-serverless",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Official Sentry SDK for Google Cloud Functions",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/google-cloud-serverless",
@@ -48,8 +48,8 @@
"access": "public"
},
"dependencies": {
- "@sentry/core": "10.25.0",
- "@sentry/node": "10.25.0",
+ "@sentry/core": "10.26.0",
+ "@sentry/node": "10.26.0",
"@types/express": "^4.17.14"
},
"devDependencies": {
diff --git a/packages/integration-shims/package.json b/packages/integration-shims/package.json
index a2535fc2b9b4..8569a5b837f6 100644
--- a/packages/integration-shims/package.json
+++ b/packages/integration-shims/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry-internal/integration-shims",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Shims for integrations in Sentry SDK.",
"main": "build/cjs/index.js",
"module": "build/esm/index.js",
@@ -56,7 +56,7 @@
"url": "https://github.com/getsentry/sentry-javascript/issues"
},
"dependencies": {
- "@sentry/core": "10.25.0"
+ "@sentry/core": "10.26.0"
},
"engines": {
"node": ">=18"
diff --git a/packages/nestjs/package.json b/packages/nestjs/package.json
index 80fdb673cc6d..53c3064ed08f 100644
--- a/packages/nestjs/package.json
+++ b/packages/nestjs/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry/nestjs",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Official Sentry SDK for NestJS",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/nestjs",
@@ -49,8 +49,8 @@
"@opentelemetry/instrumentation": "^0.204.0",
"@opentelemetry/instrumentation-nestjs-core": "0.50.0",
"@opentelemetry/semantic-conventions": "^1.37.0",
- "@sentry/core": "10.25.0",
- "@sentry/node": "10.25.0"
+ "@sentry/core": "10.26.0",
+ "@sentry/node": "10.26.0"
},
"devDependencies": {
"@nestjs/common": "^10.0.0",
diff --git a/packages/nextjs/package.json b/packages/nextjs/package.json
index 47adab59a32d..15b6a2bf3040 100644
--- a/packages/nextjs/package.json
+++ b/packages/nextjs/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry/nextjs",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Official Sentry SDK for Next.js",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/nextjs",
@@ -79,13 +79,13 @@
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/semantic-conventions": "^1.37.0",
"@rollup/plugin-commonjs": "28.0.1",
- "@sentry-internal/browser-utils": "10.25.0",
+ "@sentry-internal/browser-utils": "10.26.0",
"@sentry/bundler-plugin-core": "^4.3.0",
- "@sentry/core": "10.25.0",
- "@sentry/node": "10.25.0",
- "@sentry/opentelemetry": "10.25.0",
- "@sentry/react": "10.25.0",
- "@sentry/vercel-edge": "10.25.0",
+ "@sentry/core": "10.26.0",
+ "@sentry/node": "10.26.0",
+ "@sentry/opentelemetry": "10.26.0",
+ "@sentry/react": "10.26.0",
+ "@sentry/vercel-edge": "10.26.0",
"@sentry/webpack-plugin": "^4.3.0",
"resolve": "1.22.8",
"rollup": "^4.35.0",
diff --git a/packages/node-core/package.json b/packages/node-core/package.json
index 43af0a610e61..89dbe5461165 100644
--- a/packages/node-core/package.json
+++ b/packages/node-core/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry/node-core",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Sentry Node-Core SDK",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/node-core",
@@ -67,8 +67,8 @@
},
"dependencies": {
"@apm-js-collab/tracing-hooks": "^0.3.1",
- "@sentry/core": "10.25.0",
- "@sentry/opentelemetry": "10.25.0",
+ "@sentry/core": "10.26.0",
+ "@sentry/opentelemetry": "10.26.0",
"import-in-the-middle": "^1.14.2"
},
"devDependencies": {
diff --git a/packages/node-core/src/index.ts b/packages/node-core/src/index.ts
index 7557d73c74a2..9b5286db37dd 100644
--- a/packages/node-core/src/index.ts
+++ b/packages/node-core/src/index.ts
@@ -43,7 +43,6 @@ export { initializeEsmLoader } from './sdk/esmLoader';
export { isCjs } from './utils/detection';
export { ensureIsWrapped } from './utils/ensureIsWrapped';
export { createMissingInstrumentationContext } from './utils/createMissingInstrumentationContext';
-export { envToBool } from './utils/envToBool';
export { makeNodeTransport, type NodeTransportOptions } from './transports';
export type { HTTPModuleRequestIncomingMessage } from './transports/http-module';
export { NodeClient } from './sdk/client';
diff --git a/packages/node-core/src/sdk/index.ts b/packages/node-core/src/sdk/index.ts
index 0814ab401535..f8010e09b5c6 100644
--- a/packages/node-core/src/sdk/index.ts
+++ b/packages/node-core/src/sdk/index.ts
@@ -4,6 +4,7 @@ import {
consoleIntegration,
consoleSandbox,
debug,
+ envToBool,
functionToStringIntegration,
getCurrentScope,
getIntegrationsToSetup,
@@ -13,6 +14,7 @@ import {
linkedErrorsIntegration,
propagationContextFromHeaders,
requestDataIntegration,
+ resolveSpotlightOptions,
stackParserFromStackParserOptions,
} from '@sentry/core';
import {
@@ -37,7 +39,6 @@ import { systemErrorIntegration } from '../integrations/systemError';
import { makeNodeTransport } from '../transports';
import type { NodeClientOptions, NodeOptions } from '../types';
import { isCjs } from '../utils/detection';
-import { envToBool } from '../utils/envToBool';
import { defaultStackParser, getSentryRelease } from './api';
import { NodeClient } from './client';
import { initializeEsmLoader } from './esmLoader';
@@ -184,21 +185,11 @@ function getClientOptions(
const release = getRelease(options.release);
// Parse spotlight configuration with proper precedence per spec
- let spotlight: boolean | string | undefined;
- if (options.spotlight === false) {
- spotlight = false;
- } else if (typeof options.spotlight === 'string') {
- spotlight = options.spotlight;
- } else {
- // options.spotlight is true or undefined
- const envBool = envToBool(process.env.SENTRY_SPOTLIGHT, { strict: true });
- const envUrl = envBool === null && process.env.SENTRY_SPOTLIGHT ? process.env.SENTRY_SPOTLIGHT : undefined;
-
- spotlight =
- options.spotlight === true
- ? (envUrl ?? true) // true: use env URL if present, otherwise true
- : (envBool ?? envUrl); // undefined: use env var (bool or URL)
- }
+ const envBool = envToBool(process.env.SENTRY_SPOTLIGHT, { strict: true });
+ const envSpotlight = envBool !== null ? envBool : process.env.SENTRY_SPOTLIGHT;
+ // Note: resolveSpotlightOptions is the single source of truth for filtering empty/whitespace strings
+ // and ensures that empty strings are NEVER returned (returns undefined instead)
+ const spotlight = resolveSpotlightOptions(options.spotlight, envSpotlight);
const tracesSampleRate = getTracesSampleRate(options.tracesSampleRate);
diff --git a/packages/node-core/test/sdk/init.test.ts b/packages/node-core/test/sdk/init.test.ts
index 1332b89abcd6..04cfc75649f1 100644
--- a/packages/node-core/test/sdk/init.test.ts
+++ b/packages/node-core/test/sdk/init.test.ts
@@ -323,6 +323,24 @@ describe('init()', () => {
expect(client?.getOptions().spotlight).toBe(true);
expect(client?.getOptions().integrations.some(integration => integration.name === 'Spotlight')).toBe(true);
});
+
+ it('treats empty string env var as undefined (no spotlight)', () => {
+ process.env.SENTRY_SPOTLIGHT = '';
+
+ const client = init({ dsn: PUBLIC_DSN });
+
+ expect(client?.getOptions().spotlight).toBeUndefined();
+ expect(client?.getOptions().integrations.some(integration => integration.name === 'Spotlight')).toBe(false);
+ });
+
+ it('treats whitespace-only string env var as undefined (no spotlight)', () => {
+ process.env.SENTRY_SPOTLIGHT = ' ';
+
+ const client = init({ dsn: PUBLIC_DSN });
+
+ expect(client?.getOptions().spotlight).toBeUndefined();
+ expect(client?.getOptions().integrations.some(integration => integration.name === 'Spotlight')).toBe(false);
+ });
});
});
});
diff --git a/packages/node-native/package.json b/packages/node-native/package.json
index 23ce0068019c..9a4c40818556 100644
--- a/packages/node-native/package.json
+++ b/packages/node-native/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry/node-native",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Native Tools for the Official Sentry Node.js SDK",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/node-native",
@@ -64,8 +64,8 @@
},
"dependencies": {
"@sentry-internal/node-native-stacktrace": "^0.2.2",
- "@sentry/core": "10.25.0",
- "@sentry/node": "10.25.0"
+ "@sentry/core": "10.26.0",
+ "@sentry/node": "10.26.0"
},
"devDependencies": {
"@types/node": "^18.19.1"
diff --git a/packages/node/package.json b/packages/node/package.json
index 830fb510f9f9..6f0bec49c92a 100644
--- a/packages/node/package.json
+++ b/packages/node/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry/node",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Sentry Node SDK using OpenTelemetry for performance instrumentation",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/node",
@@ -95,9 +95,9 @@
"@opentelemetry/sdk-trace-base": "^2.1.0",
"@opentelemetry/semantic-conventions": "^1.37.0",
"@prisma/instrumentation": "6.15.0",
- "@sentry/core": "10.25.0",
- "@sentry/node-core": "10.25.0",
- "@sentry/opentelemetry": "10.25.0",
+ "@sentry/core": "10.26.0",
+ "@sentry/node-core": "10.26.0",
+ "@sentry/opentelemetry": "10.26.0",
"import-in-the-middle": "^1.14.2",
"minimatch": "^9.0.0"
},
diff --git a/packages/node/src/preload.ts b/packages/node/src/preload.ts
index 615ab0c1a008..7684449ee524 100644
--- a/packages/node/src/preload.ts
+++ b/packages/node/src/preload.ts
@@ -1,4 +1,4 @@
-import { envToBool } from '@sentry/node-core';
+import { envToBool } from '@sentry/core';
import { preloadOpenTelemetry } from './sdk/initOtel';
const debug = envToBool(process.env.SENTRY_DEBUG);
diff --git a/packages/nuxt/package.json b/packages/nuxt/package.json
index 3a9679553475..e054d1b9938a 100644
--- a/packages/nuxt/package.json
+++ b/packages/nuxt/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry/nuxt",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Official Sentry SDK for Nuxt",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/nuxt",
@@ -49,13 +49,13 @@
},
"dependencies": {
"@nuxt/kit": "^3.13.2",
- "@sentry/browser": "10.25.0",
- "@sentry/cloudflare": "10.25.0",
- "@sentry/core": "10.25.0",
- "@sentry/node": "10.25.0",
+ "@sentry/browser": "10.26.0",
+ "@sentry/cloudflare": "10.26.0",
+ "@sentry/core": "10.26.0",
+ "@sentry/node": "10.26.0",
"@sentry/rollup-plugin": "^4.3.0",
"@sentry/vite-plugin": "^4.3.0",
- "@sentry/vue": "10.25.0"
+ "@sentry/vue": "10.26.0"
},
"devDependencies": {
"@nuxt/module-builder": "^0.8.4",
diff --git a/packages/opentelemetry/package.json b/packages/opentelemetry/package.json
index 94457ff83b65..95b7f54cd000 100644
--- a/packages/opentelemetry/package.json
+++ b/packages/opentelemetry/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry/opentelemetry",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Official Sentry utilities for OpenTelemetry",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/opentelemetry",
@@ -39,7 +39,7 @@
"access": "public"
},
"dependencies": {
- "@sentry/core": "10.25.0"
+ "@sentry/core": "10.26.0"
},
"peerDependencies": {
"@opentelemetry/api": "^1.9.0",
diff --git a/packages/profiling-node/package.json b/packages/profiling-node/package.json
index 7040f0a53c21..e897b8d5611e 100644
--- a/packages/profiling-node/package.json
+++ b/packages/profiling-node/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry/profiling-node",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Official Sentry SDK for Node.js Profiling",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/profiling-node",
@@ -63,8 +63,8 @@
},
"dependencies": {
"@sentry-internal/node-cpu-profiler": "^2.2.0",
- "@sentry/core": "10.25.0",
- "@sentry/node": "10.25.0"
+ "@sentry/core": "10.26.0",
+ "@sentry/node": "10.26.0"
},
"devDependencies": {
"@types/node": "^18.19.1"
diff --git a/packages/react-router/package.json b/packages/react-router/package.json
index 52dd1a71fee7..3d57ad54469f 100644
--- a/packages/react-router/package.json
+++ b/packages/react-router/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry/react-router",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Official Sentry SDK for React Router (Framework)",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/react-router",
@@ -49,11 +49,11 @@
"@opentelemetry/core": "^2.1.0",
"@opentelemetry/instrumentation": "^0.204.0",
"@opentelemetry/semantic-conventions": "^1.37.0",
- "@sentry/browser": "10.25.0",
+ "@sentry/browser": "10.26.0",
"@sentry/cli": "^2.56.0",
- "@sentry/core": "10.25.0",
- "@sentry/node": "10.25.0",
- "@sentry/react": "10.25.0",
+ "@sentry/core": "10.26.0",
+ "@sentry/node": "10.26.0",
+ "@sentry/react": "10.26.0",
"@sentry/vite-plugin": "^4.1.0",
"glob": "11.0.1"
},
diff --git a/packages/react/package.json b/packages/react/package.json
index c7e7163a9a5e..c51a7e2d3ee8 100644
--- a/packages/react/package.json
+++ b/packages/react/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry/react",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Official Sentry SDK for React.js",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/react",
@@ -39,8 +39,8 @@
"access": "public"
},
"dependencies": {
- "@sentry/browser": "10.25.0",
- "@sentry/core": "10.25.0",
+ "@sentry/browser": "10.26.0",
+ "@sentry/core": "10.26.0",
"hoist-non-react-statics": "^3.3.2"
},
"peerDependencies": {
diff --git a/packages/remix/package.json b/packages/remix/package.json
index 9a255af786ce..667f77d53648 100644
--- a/packages/remix/package.json
+++ b/packages/remix/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry/remix",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Official Sentry SDK for Remix",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/remix",
@@ -69,9 +69,9 @@
"@opentelemetry/semantic-conventions": "^1.37.0",
"@remix-run/router": "1.x",
"@sentry/cli": "^2.56.0",
- "@sentry/core": "10.25.0",
- "@sentry/node": "10.25.0",
- "@sentry/react": "10.25.0",
+ "@sentry/core": "10.26.0",
+ "@sentry/node": "10.26.0",
+ "@sentry/react": "10.26.0",
"glob": "^10.3.4",
"yargs": "^17.6.0"
},
diff --git a/packages/replay-canvas/core b/packages/replay-canvas/core
new file mode 100644
index 000000000000..c0595c9682e7
Binary files /dev/null and b/packages/replay-canvas/core differ
diff --git a/packages/replay-canvas/package.json b/packages/replay-canvas/package.json
index 491d919e55dc..63ee871ddfdf 100644
--- a/packages/replay-canvas/package.json
+++ b/packages/replay-canvas/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry-internal/replay-canvas",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Replay canvas integration",
"main": "build/npm/cjs/index.js",
"module": "build/npm/esm/index.js",
@@ -69,8 +69,8 @@
"@sentry-internal/rrweb": "2.40.0"
},
"dependencies": {
- "@sentry-internal/replay": "10.25.0",
- "@sentry/core": "10.25.0"
+ "@sentry-internal/replay": "10.26.0",
+ "@sentry/core": "10.26.0"
},
"engines": {
"node": ">=18"
diff --git a/packages/replay-internal/package.json b/packages/replay-internal/package.json
index d2e1efbd84b7..af121d6a74c0 100644
--- a/packages/replay-internal/package.json
+++ b/packages/replay-internal/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry-internal/replay",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "User replays for Sentry",
"main": "build/npm/cjs/index.js",
"module": "build/npm/esm/index.js",
@@ -81,7 +81,7 @@
"homepage": "https://docs.sentry.io/platforms/javascript/session-replay/",
"devDependencies": {
"@babel/core": "^7.27.7",
- "@sentry-internal/replay-worker": "10.25.0",
+ "@sentry-internal/replay-worker": "10.26.0",
"@sentry-internal/rrweb": "2.40.0",
"@sentry-internal/rrweb-snapshot": "2.40.0",
"fflate": "0.8.2",
@@ -90,8 +90,8 @@
"node-fetch": "^2.6.7"
},
"dependencies": {
- "@sentry-internal/browser-utils": "10.25.0",
- "@sentry/core": "10.25.0"
+ "@sentry-internal/browser-utils": "10.26.0",
+ "@sentry/core": "10.26.0"
},
"engines": {
"node": ">=18"
diff --git a/packages/replay-worker/package.json b/packages/replay-worker/package.json
index a0d25235c7d7..e9a968061841 100644
--- a/packages/replay-worker/package.json
+++ b/packages/replay-worker/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry-internal/replay-worker",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Worker for @sentry-internal/replay",
"main": "build/esm/index.js",
"module": "build/esm/index.js",
diff --git a/packages/solid/package.json b/packages/solid/package.json
index bdb3dbe50a15..c75a0eadb4ce 100644
--- a/packages/solid/package.json
+++ b/packages/solid/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry/solid",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Official Sentry SDK for Solid",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/solid",
@@ -54,8 +54,8 @@
"access": "public"
},
"dependencies": {
- "@sentry/browser": "10.25.0",
- "@sentry/core": "10.25.0"
+ "@sentry/browser": "10.26.0",
+ "@sentry/core": "10.26.0"
},
"peerDependencies": {
"@solidjs/router": "^0.13.4",
diff --git a/packages/solidstart/package.json b/packages/solidstart/package.json
index bb4acc3404f4..8bb0e4e0471f 100644
--- a/packages/solidstart/package.json
+++ b/packages/solidstart/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry/solidstart",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Official Sentry SDK for Solid Start",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/solidstart",
@@ -66,9 +66,9 @@
}
},
"dependencies": {
- "@sentry/core": "10.25.0",
- "@sentry/node": "10.25.0",
- "@sentry/solid": "10.25.0",
+ "@sentry/core": "10.26.0",
+ "@sentry/node": "10.26.0",
+ "@sentry/solid": "10.26.0",
"@sentry/vite-plugin": "^4.1.0"
},
"devDependencies": {
diff --git a/packages/svelte/package.json b/packages/svelte/package.json
index dc8c662012c3..6e9cbdf5b54a 100644
--- a/packages/svelte/package.json
+++ b/packages/svelte/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry/svelte",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Official Sentry SDK for Svelte",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/svelte",
@@ -39,8 +39,8 @@
"access": "public"
},
"dependencies": {
- "@sentry/browser": "10.25.0",
- "@sentry/core": "10.25.0",
+ "@sentry/browser": "10.26.0",
+ "@sentry/core": "10.26.0",
"magic-string": "^0.30.0"
},
"peerDependencies": {
diff --git a/packages/sveltekit/package.json b/packages/sveltekit/package.json
index 01f88fcd60b9..7802db426793 100644
--- a/packages/sveltekit/package.json
+++ b/packages/sveltekit/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry/sveltekit",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Official Sentry SDK for SvelteKit",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/sveltekit",
@@ -48,10 +48,10 @@
},
"dependencies": {
"@babel/parser": "7.26.9",
- "@sentry/cloudflare": "10.25.0",
- "@sentry/core": "10.25.0",
- "@sentry/node": "10.25.0",
- "@sentry/svelte": "10.25.0",
+ "@sentry/cloudflare": "10.26.0",
+ "@sentry/core": "10.26.0",
+ "@sentry/node": "10.26.0",
+ "@sentry/svelte": "10.26.0",
"@sentry/vite-plugin": "^4.1.0",
"magic-string": "0.30.7",
"recast": "0.23.11",
diff --git a/packages/tanstackstart-react/package.json b/packages/tanstackstart-react/package.json
index 49c0bf12d971..03688bdd6aad 100644
--- a/packages/tanstackstart-react/package.json
+++ b/packages/tanstackstart-react/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry/tanstackstart-react",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Official Sentry SDK for TanStack Start React",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/tanstackstart-react",
@@ -52,10 +52,10 @@
"dependencies": {
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/semantic-conventions": "^1.37.0",
- "@sentry-internal/browser-utils": "10.25.0",
- "@sentry/core": "10.25.0",
- "@sentry/node": "10.25.0",
- "@sentry/react": "10.25.0"
+ "@sentry-internal/browser-utils": "10.26.0",
+ "@sentry/core": "10.26.0",
+ "@sentry/node": "10.26.0",
+ "@sentry/react": "10.26.0"
},
"scripts": {
"build": "run-p build:transpile build:types",
diff --git a/packages/tanstackstart/package.json b/packages/tanstackstart/package.json
index 56e0c7992fea..3918ecd9a3fa 100644
--- a/packages/tanstackstart/package.json
+++ b/packages/tanstackstart/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry/tanstackstart",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Utilities for the Sentry TanStack Start SDKs",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/tanstackstart",
diff --git a/packages/types/package.json b/packages/types/package.json
index 1c53b6c05275..2287d86014da 100644
--- a/packages/types/package.json
+++ b/packages/types/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry/types",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Types for all Sentry JavaScript SDKs",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/types",
@@ -57,7 +57,7 @@
"yalc:publish": "yalc publish --push --sig"
},
"dependencies": {
- "@sentry/core": "10.25.0"
+ "@sentry/core": "10.26.0"
},
"volta": {
"extends": "../../package.json"
diff --git a/packages/typescript/package.json b/packages/typescript/package.json
index c1c99704c346..ab02fe16f828 100644
--- a/packages/typescript/package.json
+++ b/packages/typescript/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry-internal/typescript",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Typescript configuration used at Sentry",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/typescript",
diff --git a/packages/vercel-edge/package.json b/packages/vercel-edge/package.json
index c7c6db556ccb..d5c9ef78b8c1 100644
--- a/packages/vercel-edge/package.json
+++ b/packages/vercel-edge/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry/vercel-edge",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Official Sentry SDK for the Vercel Edge Runtime",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/vercel-edge",
@@ -41,14 +41,14 @@
"dependencies": {
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/resources": "^2.1.0",
- "@sentry/core": "10.25.0"
+ "@sentry/core": "10.26.0"
},
"devDependencies": {
"@edge-runtime/types": "3.0.1",
"@opentelemetry/core": "^2.1.0",
"@opentelemetry/sdk-trace-base": "^2.1.0",
"@opentelemetry/semantic-conventions": "^1.37.0",
- "@sentry/opentelemetry": "10.25.0"
+ "@sentry/opentelemetry": "10.26.0"
},
"scripts": {
"build": "run-p build:transpile build:types",
diff --git a/packages/vue/package.json b/packages/vue/package.json
index 31bef1a870c8..abdb956018c6 100644
--- a/packages/vue/package.json
+++ b/packages/vue/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry/vue",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Official Sentry SDK for Vue.js",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/vue",
@@ -39,8 +39,8 @@
"access": "public"
},
"dependencies": {
- "@sentry/browser": "10.25.0",
- "@sentry/core": "10.25.0"
+ "@sentry/browser": "10.26.0",
+ "@sentry/core": "10.26.0"
},
"peerDependencies": {
"pinia": "2.x || 3.x",
diff --git a/packages/wasm/package.json b/packages/wasm/package.json
index f7a97139c120..2e7883644276 100644
--- a/packages/wasm/package.json
+++ b/packages/wasm/package.json
@@ -1,6 +1,6 @@
{
"name": "@sentry/wasm",
- "version": "10.25.0",
+ "version": "10.26.0",
"description": "Support for WASM.",
"repository": "git://github.com/getsentry/sentry-javascript.git",
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/wasm",
@@ -39,8 +39,8 @@
"access": "public"
},
"dependencies": {
- "@sentry/browser": "10.25.0",
- "@sentry/core": "10.25.0"
+ "@sentry/browser": "10.26.0",
+ "@sentry/core": "10.26.0"
},
"scripts": {
"build": "run-p build:transpile build:bundle build:types",