Skip to content

Commit 70513b7

Browse files
committed
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
1 parent 993303c commit 70513b7

File tree

7 files changed

+40
-2
lines changed

7 files changed

+40
-2
lines changed

packages/browser/src/client.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,18 @@ type BrowserSpecificOptions = BrowserClientReplayOptions &
6363
* @default false
6464
*/
6565
propagateTraceparent?: boolean;
66+
67+
/**
68+
* If you use Spotlight by Sentry during development, use
69+
* this option to forward captured Sentry events to Spotlight.
70+
*
71+
* Either set it to true, or provide a specific Spotlight Sidecar URL.
72+
*
73+
* More details: https://spotlightjs.com/
74+
*
75+
* IMPORTANT: Only set this option to `true` while developing, not in production!
76+
*/
77+
spotlight?: boolean | string;
6678
};
6779
/**
6880
* Configuration options for the Sentry Browser SDK.

packages/browser/src/sdk.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { Client, Integration, Options } from '@sentry/core';
22
import {
33
dedupeIntegration,
4+
envToBool,
45
functionToStringIntegration,
56
getIntegrationsToSetup,
67
inboundFiltersIntegration,
@@ -15,6 +16,7 @@ import { browserSessionIntegration } from './integrations/browsersession';
1516
import { globalHandlersIntegration } from './integrations/globalhandlers';
1617
import { httpContextIntegration } from './integrations/httpcontext';
1718
import { linkedErrorsIntegration } from './integrations/linkederrors';
19+
import { INTEGRATION_NAME as SPOTLIGHT_INTEGRATION_NAME, spotlightBrowserIntegration } from './integrations/spotlight';
1820
import { defaultStackParser } from './stack-parsers';
1921
import { makeFetchTransport } from './transports/fetch';
2022
import { checkAndWarnIfIsEmbeddedBrowserExtension } from './utils/detectBrowserExtension';
@@ -90,6 +92,17 @@ export function init(options: BrowserOptions = {}): Client | undefined {
9092
const shouldDisableBecauseIsBrowserExtenstion =
9193
!options.skipBrowserExtensionCheck && checkAndWarnIfIsEmbeddedBrowserExtension();
9294

95+
// Read spotlight config from env var with graceful fallback
96+
// This will be replaced at build time by bundlers like webpack/vite
97+
let spotlightFromEnv: boolean | string | undefined;
98+
if (typeof process !== 'undefined' && process.env && process.env.SENTRY_SPOTLIGHT !== undefined) {
99+
const envValue = process.env.SENTRY_SPOTLIGHT;
100+
const parsedEnvValue = envToBool(envValue, { strict: true });
101+
spotlightFromEnv = parsedEnvValue ?? envValue;
102+
}
103+
104+
const spotlight = options.spotlight ?? spotlightFromEnv;
105+
93106
const clientOptions: BrowserClientOptions = {
94107
...options,
95108
enabled: shouldDisableBecauseIsBrowserExtenstion ? false : options.enabled,
@@ -100,7 +113,18 @@ export function init(options: BrowserOptions = {}): Client | undefined {
100113
options.defaultIntegrations == null ? getDefaultIntegrations(options) : options.defaultIntegrations,
101114
}),
102115
transport: options.transport || makeFetchTransport,
116+
spotlight,
103117
};
118+
119+
// Auto-add spotlight integration if enabled and not already present
120+
if (spotlight && !clientOptions.integrations.some(({ name }) => name === SPOTLIGHT_INTEGRATION_NAME)) {
121+
clientOptions.integrations.push(
122+
spotlightBrowserIntegration({
123+
sidecarUrl: typeof spotlight === 'string' ? spotlight : undefined,
124+
}),
125+
);
126+
}
127+
104128
return initAndBind(BrowserClient, clientOptions);
105129
}
106130

packages/core/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,8 @@ export { flushIfServerless } from './utils/flushIfServerless';
313313
export { SDK_VERSION } from './utils/version';
314314
export { getDebugImagesForResources, getFilenameToDebugIdMap } from './utils/debug-ids';
315315
export { escapeStringForRegex } from './vendor/escapeStringForRegex';
316+
export { envToBool, TRUTHY_ENV_VALUES, FALSY_ENV_VALUES } from './utils/envToBool';
317+
export type { BoolCastOptions, StrictBoolCast, LooseBoolCast } from './utils/envToBool';
316318

317319
export type { Attachment } from './types-hoist/attachment';
318320
export type {
File renamed without changes.

packages/node-core/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ export { initializeEsmLoader } from './sdk/esmLoader';
4343
export { isCjs } from './utils/detection';
4444
export { ensureIsWrapped } from './utils/ensureIsWrapped';
4545
export { createMissingInstrumentationContext } from './utils/createMissingInstrumentationContext';
46-
export { envToBool } from './utils/envToBool';
4746
export { makeNodeTransport, type NodeTransportOptions } from './transports';
4847
export type { HTTPModuleRequestIncomingMessage } from './transports/http-module';
4948
export { NodeClient } from './sdk/client';
@@ -112,6 +111,7 @@ export {
112111
startSession,
113112
captureSession,
114113
endSession,
114+
envToBool,
115115
addIntegration,
116116
startSpan,
117117
startSpanManual,

packages/node-core/src/sdk/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
consoleIntegration,
55
consoleSandbox,
66
debug,
7+
envToBool,
78
functionToStringIntegration,
89
getCurrentScope,
910
getIntegrationsToSetup,
@@ -37,7 +38,6 @@ import { systemErrorIntegration } from '../integrations/systemError';
3738
import { makeNodeTransport } from '../transports';
3839
import type { NodeClientOptions, NodeOptions } from '../types';
3940
import { isCjs } from '../utils/detection';
40-
import { envToBool } from '../utils/envToBool';
4141
import { defaultStackParser, getSentryRelease } from './api';
4242
import { NodeClient } from './client';
4343
import { initializeEsmLoader } from './esmLoader';

0 commit comments

Comments
 (0)