From 70513b77fa20cb5dc82d4932b48ef5e1c685254f Mon Sep 17 00:00:00 2001 From: Burak Yigit Kaya Date: Wed, 29 Oct 2025 11:47:25 +0300 Subject: [PATCH 1/4] feat(browser): Enable Spotlight via SENTRY_SPOTLIGHT env var - Move envToBool utility from node-core to core for code sharing - Add spotlight option to BrowserSpecificOptions type - Support SENTRY_SPOTLIGHT env var in browser SDK with graceful fallback - Auto-inject spotlightBrowserIntegration when enabled via env var - Match Node.js behavior: truthy values use default URL, custom strings use that URL --- packages/browser/src/client.ts | 12 ++++++++++ packages/browser/src/sdk.ts | 24 +++++++++++++++++++ packages/core/src/index.ts | 2 ++ .../src/utils/envToBool.ts | 0 .../test/utils/envToBool.test.ts | 0 packages/node-core/src/index.ts | 2 +- packages/node-core/src/sdk/index.ts | 2 +- 7 files changed, 40 insertions(+), 2 deletions(-) rename packages/{node-core => core}/src/utils/envToBool.ts (100%) rename packages/{node-core => core}/test/utils/envToBool.test.ts (100%) diff --git a/packages/browser/src/client.ts b/packages/browser/src/client.ts index 1b4289d66992..263c6d4e4f40 100644 --- a/packages/browser/src/client.ts +++ b/packages/browser/src/client.ts @@ -63,6 +63,18 @@ type BrowserSpecificOptions = BrowserClientReplayOptions & * @default false */ propagateTraceparent?: boolean; + + /** + * If you use Spotlight by Sentry during development, use + * this option to forward captured Sentry events to Spotlight. + * + * Either set it to true, or provide a specific Spotlight Sidecar URL. + * + * More details: https://spotlightjs.com/ + * + * IMPORTANT: Only set this option to `true` while developing, not in production! + */ + spotlight?: boolean | string; }; /** * Configuration options for the Sentry Browser SDK. diff --git a/packages/browser/src/sdk.ts b/packages/browser/src/sdk.ts index 7b5d67c636ae..615fbb94b8fb 100644 --- a/packages/browser/src/sdk.ts +++ b/packages/browser/src/sdk.ts @@ -1,6 +1,7 @@ import type { Client, Integration, Options } from '@sentry/core'; import { dedupeIntegration, + envToBool, functionToStringIntegration, getIntegrationsToSetup, inboundFiltersIntegration, @@ -15,6 +16,7 @@ import { browserSessionIntegration } from './integrations/browsersession'; import { globalHandlersIntegration } from './integrations/globalhandlers'; import { httpContextIntegration } from './integrations/httpcontext'; import { linkedErrorsIntegration } from './integrations/linkederrors'; +import { INTEGRATION_NAME as SPOTLIGHT_INTEGRATION_NAME, spotlightBrowserIntegration } from './integrations/spotlight'; import { defaultStackParser } from './stack-parsers'; import { makeFetchTransport } from './transports/fetch'; import { checkAndWarnIfIsEmbeddedBrowserExtension } from './utils/detectBrowserExtension'; @@ -90,6 +92,17 @@ export function init(options: BrowserOptions = {}): Client | undefined { const shouldDisableBecauseIsBrowserExtenstion = !options.skipBrowserExtensionCheck && checkAndWarnIfIsEmbeddedBrowserExtension(); + // Read spotlight config from env var with graceful fallback + // This will be replaced at build time by bundlers like webpack/vite + let spotlightFromEnv: boolean | string | undefined; + if (typeof process !== 'undefined' && process.env && process.env.SENTRY_SPOTLIGHT !== undefined) { + const envValue = process.env.SENTRY_SPOTLIGHT; + const parsedEnvValue = envToBool(envValue, { strict: true }); + spotlightFromEnv = parsedEnvValue ?? envValue; + } + + const spotlight = options.spotlight ?? spotlightFromEnv; + const clientOptions: BrowserClientOptions = { ...options, enabled: shouldDisableBecauseIsBrowserExtenstion ? false : options.enabled, @@ -100,7 +113,18 @@ export function init(options: BrowserOptions = {}): Client | undefined { options.defaultIntegrations == null ? getDefaultIntegrations(options) : options.defaultIntegrations, }), transport: options.transport || makeFetchTransport, + spotlight, }; + + // Auto-add spotlight integration if enabled and not already present + if (spotlight && !clientOptions.integrations.some(({ name }) => name === SPOTLIGHT_INTEGRATION_NAME)) { + clientOptions.integrations.push( + spotlightBrowserIntegration({ + sidecarUrl: typeof spotlight === 'string' ? spotlight : undefined, + }), + ); + } + return initAndBind(BrowserClient, clientOptions); } diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index f3b29009b9ce..5718d8deee17 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -313,6 +313,8 @@ export { flushIfServerless } from './utils/flushIfServerless'; export { SDK_VERSION } from './utils/version'; export { getDebugImagesForResources, getFilenameToDebugIdMap } from './utils/debug-ids'; export { escapeStringForRegex } from './vendor/escapeStringForRegex'; +export { envToBool, TRUTHY_ENV_VALUES, FALSY_ENV_VALUES } from './utils/envToBool'; +export type { BoolCastOptions, StrictBoolCast, LooseBoolCast } from './utils/envToBool'; export type { Attachment } from './types-hoist/attachment'; export type { 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/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/node-core/src/index.ts b/packages/node-core/src/index.ts index 7557d73c74a2..200855f928ab 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'; @@ -112,6 +111,7 @@ export { startSession, captureSession, endSession, + envToBool, addIntegration, startSpan, startSpanManual, diff --git a/packages/node-core/src/sdk/index.ts b/packages/node-core/src/sdk/index.ts index d53f5d4faefb..24ded762a3e1 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, @@ -37,7 +38,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'; From 7e0d482809fb4657ceb91a0a758bfc9995d14e9b Mon Sep 17 00:00:00 2001 From: Burak Yigit Kaya Date: Wed, 29 Oct 2025 11:54:54 +0300 Subject: [PATCH 2/4] meta(changelog): Add entry for Spotlight env var support --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b3b35020083..91ecea440663 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ - "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott +### Other Changes + +- feat(browser): Enable Spotlight via `SENTRY_SPOTLIGHT` env var ([#18050](https://github.com/getsentry/sentry-javascript/pull/18050)) + Work in this release was contributed by @hanseo0507. Thank you for your contribution! ## 10.22.0 From ea50a4a1687e7abd8dd31660bba61db1cc2f4927 Mon Sep 17 00:00:00 2001 From: Burak Yigit Kaya Date: Wed, 29 Oct 2025 11:57:46 +0300 Subject: [PATCH 3/4] meta(changelog): Clean up CHANGELOG entry --- CHANGELOG.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 91ecea440663..7a144a18264f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,6 @@ ## Unreleased -- "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott - -### Other Changes - - feat(browser): Enable Spotlight via `SENTRY_SPOTLIGHT` env var ([#18050](https://github.com/getsentry/sentry-javascript/pull/18050)) Work in this release was contributed by @hanseo0507. Thank you for your contribution! From 03877a9be3a04bc084fd963fca222de710452547 Mon Sep 17 00:00:00 2001 From: Burak Yigit Kaya Date: Wed, 29 Oct 2025 17:03:10 +0300 Subject: [PATCH 4/4] meta(changelog): Document truthy/falsy values for SENTRY_SPOTLIGHT --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a144a18264f..98fcc5ebcce1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,9 @@ ## Unreleased - feat(browser): Enable Spotlight via `SENTRY_SPOTLIGHT` env var ([#18050](https://github.com/getsentry/sentry-javascript/pull/18050)) + - Truthy values (`true`, `t`, `y`, `yes`, `on`, `1`) enable Spotlight with the default URL + - Any other non-falsy string value is used as a custom Spotlight Sidecar URL + - Falsy values (`false`, `f`, `n`, `no`, `off`, `0`) disable Spotlight Work in this release was contributed by @hanseo0507. Thank you for your contribution!