Skip to content

Commit 855ff97

Browse files
committed
?
1 parent ca898d9 commit 855ff97

File tree

4 files changed

+28
-91
lines changed

4 files changed

+28
-91
lines changed

dev-packages/e2e-tests/test-applications/nextjs-15-spotlight/app/page.tsx

Lines changed: 7 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -5,36 +5,17 @@ import * as Sentry from '@sentry/nextjs';
55

66
// Next.js replaces process.env.NEXT_PUBLIC_* at BUILD TIME with literal values
77
const NEXT_PUBLIC_SPOTLIGHT_VALUE = process.env.NEXT_PUBLIC_SENTRY_SPOTLIGHT;
8-
// Check internal values (these may or may not be replaced depending on bundler)
9-
const INTERNAL_SPOTLIGHT_PROCESS_ENV = process.env._sentrySpotlight;
108

119
export default function SpotlightTestPage() {
1210
const [spotlightEnabled, setSpotlightEnabled] = useState<boolean | null>(null);
1311
const [integrationNames, setIntegrationNames] = useState<string[]>([]);
14-
const [debugInfo, setDebugInfo] = useState<{
15-
internalGlobal: string;
16-
manualGlobal: string;
17-
sdkDebug: unknown;
18-
initCalled: unknown;
19-
} | null>(null);
12+
const [windowSpotlight, setWindowSpotlight] = useState<string>('loading...');
2013

2114
useEffect(() => {
22-
// Read globals at runtime (after init has run)
23-
// @ts-expect-error - accessing globalThis for debugging
24-
const internalGlobal = globalThis._sentrySpotlight;
25-
// @ts-expect-error - accessing manual global
26-
const manualGlobal = globalThis._sentrySpotlightManual;
27-
// @ts-expect-error - accessing SDK debug info
28-
const sdkDebug = globalThis._sentrySpotlightDebug;
29-
// @ts-expect-error - accessing init marker
30-
const initCalled = globalThis._sentryNextjsInitCalled;
31-
32-
setDebugInfo({
33-
internalGlobal: String(internalGlobal ?? 'undefined'),
34-
manualGlobal: String(manualGlobal ?? 'undefined'),
35-
sdkDebug,
36-
initCalled,
37-
});
15+
// Read window._sentrySpotlight at runtime
16+
// @ts-expect-error - accessing window property
17+
const windowValue = typeof window !== 'undefined' ? window._sentrySpotlight : undefined;
18+
setWindowSpotlight(String(windowValue ?? 'undefined'));
3819

3920
// Check if Spotlight integration is registered
4021
const client = Sentry.getClient();
@@ -49,11 +30,7 @@ export default function SpotlightTestPage() {
4930
// Log for debugging
5031
console.log('Spotlight test results:', {
5132
envValue: NEXT_PUBLIC_SPOTLIGHT_VALUE,
52-
internalProcessEnv: INTERNAL_SPOTLIGHT_PROCESS_ENV,
53-
internalGlobal,
54-
manualGlobal,
55-
sdkDebugInfo: sdkDebug,
56-
initCalled,
33+
windowSpotlight: windowValue,
5734
integrationFound: !!integration,
5835
clientExists: !!client,
5936
integrationNames: intNames,
@@ -67,15 +44,7 @@ export default function SpotlightTestPage() {
6744
<div data-testid="env-value">
6845
<h2>Environment Variable</h2>
6946
<p>NEXT_PUBLIC_SENTRY_SPOTLIGHT: {NEXT_PUBLIC_SPOTLIGHT_VALUE || 'undefined'}</p>
70-
<p>process.env._sentrySpotlight: {String(INTERNAL_SPOTLIGHT_PROCESS_ENV) || 'undefined'}</p>
71-
<p>globalThis._sentrySpotlight: {debugInfo?.internalGlobal || 'loading...'}</p>
72-
<p>globalThis._sentrySpotlightManual: {debugInfo?.manualGlobal || 'loading...'}</p>
73-
</div>
74-
75-
<div data-testid="sdk-debug">
76-
<h2>SDK Debug Info (what SDK saw during init)</h2>
77-
<p>init() called: {String(debugInfo?.initCalled ?? 'loading...')}</p>
78-
<pre>{debugInfo?.sdkDebug ? JSON.stringify(debugInfo.sdkDebug, null, 2) : 'No debug info'}</pre>
47+
<p>window._sentrySpotlight: {windowSpotlight}</p>
7948
</div>
8049

8150
<div data-testid="spotlight-status">
Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
// Debug: manually set the global BEFORE importing Sentry
2-
// This tests if the SDK can read globals at all
3-
// @ts-expect-error - setting global for debugging
4-
globalThis._sentrySpotlightManual = process.env.NEXT_PUBLIC_SENTRY_SPOTLIGHT;
1+
// Set the spotlight value on window BEFORE importing Sentry
2+
// Next.js replaces process.env.NEXT_PUBLIC_* at build time, so this works
3+
// The SDK will read window._sentrySpotlight during init()
4+
if (typeof window !== 'undefined') {
5+
// @ts-expect-error - setting window property for SDK to read
6+
window._sentrySpotlight = process.env.NEXT_PUBLIC_SENTRY_SPOTLIGHT;
7+
}
58

69
import * as Sentry from '@sentry/nextjs';
710

@@ -10,7 +13,6 @@ Sentry.init({
1013
dsn: process.env.NEXT_PUBLIC_E2E_TEST_DSN,
1114
tunnel: `http://localhost:3031/`,
1215
tracesSampleRate: 1.0,
13-
debug: true,
1416
// Note: We don't explicitly set spotlight here - it should be auto-enabled
15-
// from NEXT_PUBLIC_SENTRY_SPOTLIGHT env var in development mode
17+
// from window._sentrySpotlight which is set above
1618
});

dev-packages/e2e-tests/test-applications/nextjs-15-spotlight/tests/spotlight.test.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,21 @@ test.describe('Spotlight auto-enablement in Next.js development mode', () => {
77
// Wait for client-side hydration and Sentry initialization
88
await page.waitForTimeout(2000);
99

10-
// Wait a bit for useEffect to run and update state
11-
await page.waitForTimeout(1000);
10+
// Wait for React to hydrate and useEffect to run
11+
await page.waitForTimeout(2000);
1212

1313
// Check environment variable is accessible
1414
const envValue = await page.getByTestId('env-value').textContent();
1515
expect(envValue).toContain('true');
1616

1717
// Get diagnostic info before asserting
1818
const integrationNames = await page.getByTestId('integration-names').textContent();
19-
const sdkDebug = await page.getByTestId('sdk-debug').textContent();
2019

2120
// Check Spotlight integration is enabled
2221
const spotlightStatus = await page.getByTestId('spotlight-enabled').textContent();
2322
expect(
2423
spotlightStatus,
25-
`Spotlight should be ENABLED.\nEnv values: ${envValue}\nSDK Debug: ${sdkDebug}\nIntegrations: ${integrationNames}`,
24+
`Spotlight should be ENABLED.\nEnv values: ${envValue}\nIntegrations: ${integrationNames}`,
2625
).toBe('ENABLED');
2726
});
2827

packages/nextjs/src/client/index.ts

Lines changed: 10 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -44,19 +44,13 @@ const globalWithInjectedValues = GLOBAL_OBJ as typeof GLOBAL_OBJ & {
4444
_sentryRelease?: string;
4545
_experimentalThirdPartyOriginStackFrames?: string;
4646
_sentrySpotlight?: string;
47-
_sentrySpotlightManual?: string; // Debug: manually set by user in instrumentation-client.ts
4847
};
4948

5049
// Treeshakable guard to remove all code related to tracing
5150
declare const __SENTRY_TRACING__: boolean;
5251

5352
/** Inits the Sentry NextJS SDK on the browser with the React SDK. */
5453
export function init(options: BrowserOptions): Client | undefined {
55-
// Debug marker to verify this init() is being called (for e2e tests)
56-
if (typeof globalThis !== 'undefined') {
57-
(globalThis as Record<string, unknown>)._sentryNextjsInitCalled = true;
58-
}
59-
6054
if (clientIsInitialized) {
6155
consoleSandbox(() => {
6256
// eslint-disable-next-line no-console
@@ -153,55 +147,28 @@ function getDefaultIntegrations(options: BrowserOptions): Integration[] {
153147
// The value is injected at build time:
154148
// - Webpack: via DefinePlugin which replaces process.env._sentrySpotlight
155149
// - Turbopack: via valueInjectionLoader which sets globalThis._sentrySpotlight
156-
// - Manual: user can set globalThis._sentrySpotlightManual in instrumentation-client.ts
150+
// - Manual: user can set window._sentrySpotlight in instrumentation-client.ts
157151
const processEnvSpotlight = process.env._sentrySpotlight;
158152
const globalSpotlight = globalWithInjectedValues._sentrySpotlight;
159-
const manualSpotlight = globalWithInjectedValues._sentrySpotlightManual;
160-
// Also check raw globalThis directly in case GLOBAL_OBJ differs
161-
const rawGlobalThis = typeof globalThis !== 'undefined' ? globalThis : undefined;
162-
const rawManualSpotlightRaw = rawGlobalThis ? (rawGlobalThis as Record<string, unknown>)._sentrySpotlightManual : undefined;
163-
const rawManualSpotlight = typeof rawManualSpotlightRaw === 'string' ? rawManualSpotlightRaw : undefined;
164-
const spotlightEnvValue: string | undefined =
165-
processEnvSpotlight || globalSpotlight || manualSpotlight || rawManualSpotlight;
166-
167-
// Expose debug info on globalThis for test verification
168-
if (rawGlobalThis) {
169-
(rawGlobalThis as Record<string, unknown>)._sentrySpotlightDebug = {
170-
processEnvSpotlight,
171-
globalSpotlight,
172-
manualSpotlight,
173-
rawManualSpotlightRaw,
174-
rawManualSpotlight,
175-
spotlightEnvValue,
176-
optionsSpotlight: options.spotlight,
177-
GLOBAL_OBJ_keys: Object.keys(GLOBAL_OBJ),
178-
};
179-
}
180153

181-
// eslint-disable-next-line no-console
182-
console.log('[Sentry Next.js DEBUG] Spotlight detection:', {
183-
'process.env._sentrySpotlight': processEnvSpotlight,
184-
'globalThis._sentrySpotlight': globalSpotlight,
185-
'globalThis._sentrySpotlightManual': manualSpotlight,
186-
'rawGlobalThis._sentrySpotlightManual (raw)': rawManualSpotlightRaw,
187-
'rawGlobalThis._sentrySpotlightManual': rawManualSpotlight,
188-
resolved: spotlightEnvValue,
189-
'options.spotlight': options.spotlight,
190-
});
154+
// Check window directly for manual setting (most reliable in browser)
155+
// This is set in instrumentation-client.ts before Sentry.init()
156+
const windowObj = typeof window !== 'undefined' ? window : undefined;
157+
const windowSpotlight = windowObj ? (windowObj as unknown as Record<string, unknown>)._sentrySpotlight : undefined;
158+
159+
const spotlightEnvValue: string | undefined =
160+
processEnvSpotlight ||
161+
globalSpotlight ||
162+
(typeof windowSpotlight === 'string' ? windowSpotlight : undefined);
191163

192164
if (spotlightEnvValue !== undefined && options.spotlight === undefined) {
193165
const boolValue = envToBool(spotlightEnvValue, { strict: true });
194166
const spotlightConfig = boolValue !== null ? boolValue : spotlightEnvValue;
195167
const spotlightValue = resolveSpotlightOptions(undefined, spotlightConfig);
196168

197-
// eslint-disable-next-line no-console
198-
console.log('[Sentry Next.js DEBUG] Spotlight resolved:', { boolValue, spotlightConfig, spotlightValue });
199-
200169
if (spotlightValue) {
201170
const spotlightArgs = typeof spotlightValue === 'string' ? { sidecarUrl: spotlightValue } : undefined;
202171
customDefaultIntegrations.push(spotlightBrowserIntegration(spotlightArgs));
203-
// eslint-disable-next-line no-console
204-
console.log('[Sentry Next.js DEBUG] Spotlight integration ADDED');
205172
}
206173
}
207174

0 commit comments

Comments
 (0)