Skip to content

Conversation

@BYK
Copy link
Member

@BYK BYK commented Nov 13, 2025

Implements full Spotlight spec with support for multiple framework-specific
environment variable prefixes. Adds defensive environment variable access
for both process.env and import.meta.env to support various bundlers.

Supported environment variables (in priority 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 (base/official)

SENTRY_SPOTLIGHT is last as in environments like Docker Compose, we actually make the front-end env variable different than the base SENTRY_SPOTLIGHT one -- the backends need to reach docker.host.internal whereas front-ends always need localhost as we assume the browser runs on the same host with Spotlight.

Refactors envToBool utility from node-core to core package for shared usage.
Adds resolveSpotlightOptions utility to ensure consistent precedence rules
across Browser and Node SDKs.

Includes comprehensive test coverage for all new utilities and integration
tests for environment variable precedence behavior.

@github-actions
Copy link
Contributor

github-actions bot commented Nov 13, 2025

size-limit report 📦

Path Size % Change Change
@sentry/browser 24.62 kB - -
@sentry/browser - with treeshaking flags 23.13 kB - -
@sentry/browser (incl. Tracing) 41.28 kB - -
@sentry/browser (incl. Tracing, Profiling) 45.61 kB - -
@sentry/browser (incl. Tracing, Replay) 79.73 kB - -
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 69.44 kB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 84.43 kB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 96.64 kB - -
@sentry/browser (incl. Feedback) 41.29 kB - -
@sentry/browser (incl. sendFeedback) 29.29 kB - -
@sentry/browser (incl. FeedbackAsync) 34.21 kB - -
@sentry/react 26.32 kB - -
@sentry/react (incl. Tracing) 43.22 kB - -
@sentry/vue 29.11 kB - -
@sentry/vue (incl. Tracing) 43.08 kB - -
@sentry/svelte 24.64 kB - -
CDN Bundle 27.01 kB +0.25% +66 B 🔺
CDN Bundle (incl. Tracing) 41.89 kB +0.16% +66 B 🔺
CDN Bundle (incl. Tracing, Replay) 78.45 kB +0.09% +69 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) 83.92 kB +0.09% +68 B 🔺
CDN Bundle - uncompressed 79.06 kB +0.18% +136 B 🔺
CDN Bundle (incl. Tracing) - uncompressed 124.21 kB +0.11% +136 B 🔺
CDN Bundle (incl. Tracing, Replay) - uncompressed 240.24 kB +0.06% +136 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 253 kB +0.06% +136 B 🔺
@sentry/nextjs (client) 45.64 kB - -
@sentry/sveltekit (client) 41.67 kB - -
@sentry/node-core 50.93 kB +0.04% +19 B 🔺
@sentry/node 159.12 kB +0.02% +26 B 🔺
@sentry/node - without tracing 92.79 kB +0.02% +10 B 🔺
@sentry/aws-serverless 106.56 kB +0.03% +26 B 🔺

View base workflow run

@github-actions
Copy link
Contributor

github-actions bot commented Nov 13, 2025

node-overhead report 🧳

Note: This is a synthetic benchmark with a minimal express app and does not necessarily reflect the real-world performance impact in an application.

Scenario Requests/s % of Baseline Prev. Requests/s Change %
GET Baseline 8,767 - 9,103 -4%
GET With Sentry 1,344 15% 1,378 -2%
GET With Sentry (error only) 6,005 68% 6,149 -2%
POST Baseline 1,181 - 1,183 -0%
POST With Sentry 511 43% 504 +1%
POST With Sentry (error only) 1,056 89% 1,057 -0%
MYSQL Baseline 3,242 - 3,389 -4%
MYSQL With Sentry 460 14% 463 -1%
MYSQL With Sentry (error only) 2,682 83% 2,715 -1%

View base workflow run

…ration

- Add support for multiple framework/bundler-specific environment variables with proper precedence
  - SENTRY_SPOTLIGHT (highest priority - base name, supported natively by many bundlers)
  - PUBLIC_SENTRY_SPOTLIGHT (SvelteKit, Astro, Qwik)
  - NEXT_PUBLIC_SENTRY_SPOTLIGHT (Next.js)
  - VITE_SENTRY_SPOTLIGHT (Vite)
  - NUXT_PUBLIC_SENTRY_SPOTLIGHT (Nuxt.js)
  - REACT_APP_SENTRY_SPOTLIGHT (Create React App)
  - VUE_APP_SENTRY_SPOTLIGHT (Vue CLI)
  - GATSBY_SENTRY_SPOTLIGHT (Gatsby)
- Add defensive environment variable access via process.env (transformed by all major bundlers)
- Move envToBool utility from node-core to core for shared usage
- Add resolveSpotlightOptions utility for consistent precedence rules
- Update node-core and aws-serverless to use shared utilities
- Add comprehensive tests for all new utilities and SDK integration

Note: import.meta.env is intentionally not checked because bundlers only replace static
references (e.g., import.meta.env.VITE_VAR) at build time, not dynamic access. All major
bundlers transform process.env references, making it the universal solution.
@BYK BYK force-pushed the feat/spotlight-environment-variable-support branch from 92ffd33 to 6cb5513 Compare November 13, 2025 22:51
@BYK BYK force-pushed the feat/spotlight-environment-variable-support branch from 4f6dcd0 to fda3d61 Compare November 14, 2025 11:31
@BYK BYK marked this pull request as ready for review November 14, 2025 11:32
@BYK BYK requested review from Lms24, andreiborza and timfish November 14, 2025 11:32
Before submitting a pull request, please take a look at our

[Contributing](https://github.com/getsentry/sentry-javascript/blob/master/CONTRIBUTING.md)
guidelines and verify:

- [x] If you've added code that should be tested, please add tests.
- [x] Ensure your code lints and the test suite passes (`yarn lint`) &
(`yarn test`).

Fixes a test failure where `getSpotlightConfig` was returning empty or
whitespace-only strings for `SENTRY_SPOTLIGHT` environment variables,
instead of `undefined`. This change explicitly filters out such values,
aligning the function's behavior with test expectations and preventing
invalid Spotlight configurations.

---
<a
href="https://cursor.com/background-agent?bcId=bc-88bd0365-3796-47b2-bb84-29c93d0430e8"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/open-in-cursor-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/open-in-cursor-light.svg"><img alt="Open in
Cursor"
src="https://cursor.com/open-in-cursor.svg"></picture></a>&nbsp;<a
href="https://cursor.com/agents?id=bc-88bd0365-3796-47b2-bb84-29c93d0430e8"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/open-in-web-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/open-in-web-light.svg"><img alt="Open in Web"
src="https://cursor.com/open-in-web.svg"></picture></a>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
@BYK BYK requested a review from a team as a code owner November 14, 2025 16:59
Copy link
Member

@Lms24 Lms24 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First pass review. I still want to figure out why size bot reports a slight increase for the CDN bundles.

Comment on lines 3 to 9
* Checks process.env which is transformed by most bundlers (Webpack, Vite, Rollup, Rspack, Parcel, etc.)
* at build time.
*
* Note: We don't check import.meta.env because:
* 1. Bundlers only replace static references like `import.meta.env.VITE_VAR`, not dynamic access
* 2. Dynamic access causes syntax errors in unsupported environments
* 3. Most bundlers transform process.env references anyway
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

m: My impression while doing some research for #18050 (comment) was what very few bundlers inject process.env into browser bundles. For example, this code will not work in Angular.
Vite instructs checking on import.meta.env, so not sure if it double-writes to process.env (my gut feeling is no).

Did you test this in the respective frameworks? Maybe I'm also misinformed and this works just fine 😅 Ideally we can add an e2e test for at least NextJS and some Vite-based framework app to be sure.

Comment on lines 62 to 64

// No Spotlight configuration found in environment
return undefined;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

l: neat size trick: You can let the function return void and simply omit the return undefined here. Saves a couple of bytes and JS returns undefined anyway. 😅 (but feel free to ignore since this is shaken out for prod builds anyway)

Before submitting a pull request, please take a look at our

[Contributing](https://github.com/getsentry/sentry-javascript/blob/master/CONTRIBUTING.md)
guidelines and verify:

- [x] If you've added code that should be tested, please add tests.
- [x] Ensure your code lints and the test suite passes (`yarn lint`) &
(`yarn test`).

---

This PR addresses critical feedback regarding environment variable
detection, particularly for Vite-based frameworks.

**Key Changes:**

* **`packages/browser/src/utils/env.ts`**: The `getEnvValue` function
now checks both `process.env` (for Webpack, Next.js, CRA) and
`import.meta.env` (for Vite, Astro, SvelteKit). This ensures that
environment variables (like those for Spotlight) are correctly detected
across a wider range of bundlers and frameworks, fixing a significant
compatibility issue.
* **`packages/browser/test/utils/env.test.ts`**: Updated unit tests to
focus on `process.env` scenarios. Added a note explaining that
`import.meta.env` cannot be unit tested due to its read-only,
compile-time nature and is covered by e2e tests.
* **`packages/browser/src/utils/spotlightConfig.ts`**: Added a comment
to clarify the explicit `return undefined` for readability, noting its
optimization in production builds.

---
<a
href="https://cursor.com/background-agent?bcId=bc-d6001dc9-59fc-42eb-8354-a573e3ae71a9"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/open-in-cursor-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/open-in-cursor-light.svg"><img alt="Open in
Cursor"
src="https://cursor.com/open-in-cursor.svg"></picture></a>&nbsp;<a
href="https://cursor.com/agents?id=bc-d6001dc9-59fc-42eb-8354-a573e3ae71a9"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/open-in-web-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/open-in-web-light.svg"><img alt="Open in Web"
src="https://cursor.com/open-in-web.svg"></picture></a>

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
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];
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Dynamic Env Access Breaks Bundler Builds

Dynamic property access import.meta.env[key] won't work with build-time environment variable replacement in bundlers like Vite, Astro, and SvelteKit. These bundlers require static property access like import.meta.env.VARIABLE_NAME for compile-time replacement. The dynamic bracket notation will always return undefined in production builds because the object doesn't exist at runtime.

Fix in Cursor Fix in Web

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@BYK I have no idea if this is true but seems relevant! Sounds like in these cases the bundler only replaces the full string/identifier?

Copy link
Collaborator

@timfish timfish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good but needs some e2e tests of some kind otherwise we could inadvertently break this in the future.

It should be quite easy to test Vite by adding some additional tests to dev-packages/bundler-tests with the specific variables set and then check they make it into the bundle.

Then as @Lms24 says, a Nextjs test would probably be a good idea too!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants