-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
feat(browser): Add environment variable support for Spotlight configuration #18198
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
6cb5513
f16380f
fda3d61
bcff50d
cd42ebd
0ac2828
0915965
6ea8d90
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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]; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bug: Dynamic Env Access Breaks Bundler BuildsDynamic property access |
||
| if (value !== undefined) { | ||
| return value; | ||
| } | ||
| } | ||
| } catch (e) { | ||
| // Silently ignore - import.meta.env might not be accessible or might throw | ||
| } | ||
|
|
||
| return undefined; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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; | ||
| } | ||
cursor[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| // No Spotlight configuration found in environment | ||
| // Note: Implicit return of undefined saves bytes and is tree-shaken in production builds | ||
| return undefined; | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.