Skip to content

[Ember] Inline instrumentation scripts use optional chaining (?.) which cannot be transpiled and breaks older browsers #18854

@rreckonerr

Description

@rreckonerr

Is there an existing issue for this?

How do you use Sentry?

Sentry Saas (sentry.io)

Which SDK are you using?

@sentry/ember

SDK Version

10.32.1

Framework Version

Ember 5.12.0

Link to Sentry event

https://suitepad.sentry.io/issues/6562357180/events/8d726eed5115425888e405c686b1c46f/

Reproduction Example/SDK Setup

No response

Steps to Reproduce

  1. Install @sentry/ember in an Ember application
  2. Build and deploy the application
  3. Load the application in a browser without ES2020 support (e.g., Chrome 74)
  4. Observe: SyntaxError: Unexpected token '.' before any application code executes

Expected Result

Inline scripts injected by @sentry/ember should use syntax compatible with the browser environments where users may deploy their applications, or at minimum, be transpilable by the consumer's build pipeline.

Since these inline scripts bypass all user-controlled transpilation (Babel, TypeScript, etc.), they should use ES5-safe syntax:

if (window.performance && window.performance.mark) {
  window.performance.mark('@sentry/ember:initial-load-start');
}

Actual Result

Inline scripts use ES2020 optional chaining syntax:

if (window.performance?.mark) {
  window.performance.mark('@sentry/ember:initial-load-start');
}

This causes a SyntaxError in browsers that don't support optional chaining, before any application code executes:

SyntaxError: Unexpected token '.'

Users cannot transpile or polyfill this because:

  1. The script is injected directly into HTML, not bundled
  2. It executes before any polyfills or transpiled code can run
  3. It's a syntax error (parse-time), not a runtime error

Additional Context

Description

The @sentry/ember addon injects inline <script> tags for initial load performance measurement that use optional chaining syntax:

<script type="text/javascript">if (window.performance?.mark) {
  window.performance.mark('@sentry/ember:initial-load-start');
}</script>
<script type="text/javascript">if (window.performance?.mark) {
  window.performance.mark('@sentry/ember:initial-load-end');
}</script>

These scripts are injected directly into the HTML via Ember CLI's contentFor hook (in packages/ember/index.js), which means they bypass all consumer build pipelines (Babel, TypeScript, etc.). Unlike bundled SDK code that users can transpile per your documentation, these inline scripts execute before any transpilation can occur.

This causes a SyntaxError in browsers that don't support ES2020 optional chaining, preventing the application from loading entirely.

Relevant Policy & Changes

Browser Support Policy

Per the Supported Browsers documentation, the SDK requires ES2020-compatible browsers (Chrome 80+, Edge 80+, Safari 14+, Firefox 74+). For older browsers, the documentation states:

"If you need to support older browsers, we recommend transpiling the SDK using Babel or similar tooling."

However, inline scripts injected into HTML cannot be transpiled by consumers—they are inserted after the build pipeline runs.

PR #14966: Rewrite to use optional chaining & add ESLint rule

This PR deliberately introduced optional chaining across the codebase and added an ESLint rule to enforce its usage. While this is a reasonable choice for bundled code (which users can transpile), it creates an untranspilable compatibility issue when applied to inline scripts.

The Core Issue

There's a difference between:

  1. Bundled SDK code → Users can transpile this per your documentation
  2. Inline scripts injected into HTML → Users cannot transpile these; they execute before any build tooling

The current implementation treats both the same way, but inline scripts require special handling.

Proposed Solutions

Option 1: Use ES5-safe syntax in inline scripts (Recommended)

Replace optional chaining in packages/ember/vendor/initial-load-head.js and initial-load-body.js:

// Before
if (window.performance?.mark) {
  window.performance.mark('@sentry/ember:initial-load-end');
}

// After
if (window.performance && window.performance.mark) {
  window.performance.mark('@sentry/ember:initial-load-end');
}

This is a minimal change that maintains functionality while ensuring the inline scripts work in all browsers. Consider exempting inline/vendor scripts from the optional chaining ESLint rule.

Priority

React with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding +1 or me too, to help us triage it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions