Skip to content

meta(changelog): Update changelog for 9.37.0 #16892

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

Merged
merged 21 commits into from
Jul 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
bd6095c
Merge pull request #16856 from getsentry/master
github-actions[bot] Jul 9, 2025
c36e75b
feat(astro): Deprecate passing runtime config to astro integration (#…
mydea Jul 9, 2025
a5173b7
feat(vercel-edge): Do not vendor in all OpenTelemetry dependencies (#…
mydea Jul 9, 2025
60063e8
deps(nuxt): Add explicit peer dependencies & bump nitropack (#16858)
mydea Jul 9, 2025
b8e7422
feat(cloudflare): Add option to opt out of capturing errors in `wrapR…
Lms24 Jul 9, 2025
29bf0d2
fix(sveltekit): Avoid capturing `redirect()` calls as errors in Cloud…
Lms24 Jul 9, 2025
7bc6bd0
docs(react-router): Update readme for beta (#16862)
chargome Jul 9, 2025
ccb129b
fix(nextjs): Use value injection loader on `instrumentation-client.ts…
chargome Jul 9, 2025
68eef54
feat(feedback): Return the eventId into the onSubmitSuccess callback …
ryan953 Jul 9, 2025
501e442
deps(solidstart): Add explicit peer deps as devDependencies (#16860)
mydea Jul 10, 2025
2a7a74b
deps(dev): Add missing peer dependencies of dev dependencies (#16751)
mydea Jul 10, 2025
3e5eac5
feat(browser): Detect redirects when emitting navigation spans (#16324)
mydea Jul 10, 2025
5534ba9
feat(nuxt): Parametrize SSR routes (#16843)
s1gr1d Jul 10, 2025
5356feb
ci: Update dependabot config to include playwright (#16871)
mydea Jul 10, 2025
ca28a7b
chore(nuxt): Add `@sentry/cloudflare` as dependency (#16873)
s1gr1d Jul 10, 2025
0df39c6
deps-dev: Bump `@playwright/test` to `~1.53.2` (#16803)
mydea Jul 10, 2025
1864b22
feat(browser): Add `beforeStartNavigationSpan` lifecycle hook (#16863)
Lms24 Jul 10, 2025
1ad6d58
fix(browser): Ensure standalone CLS and LCP spans have traceId of pag…
Lms24 Jul 10, 2025
7a8840d
docs(nextjs): Update `deleteSourcemapsAfterUpload` jsdoc default valu…
zachkirsch Jul 10, 2025
affebb4
test(nuxt): Add unit tests for catch-all routes (#16891)
s1gr1d Jul 10, 2025
e2ca660
meta(changelog): Update changelog for 9.37.0
s1gr1d Jul 10, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ updates:
- dependency-name: '@sentry/*'
- dependency-name: '@opentelemetry/*'
- dependency-name: '@prisma/instrumentation'
- dependency-name: 'opentelemetry-instrumentation-remix'
- dependency-name: '@playwright/test'
versioning-strategy: increase
commit-message:
prefix: feat
Expand Down
24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,30 @@

- "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott

## 9.37.0

### Important Changes

- **feat(nuxt): Parametrize SSR routes ([#16843](https://github.com/getsentry/sentry-javascript/pull/16843))**

When requesting dynamic or catch-all routes in Nuxt, those will now be shown as parameterized routes in Sentry.
For example, `/users/123` will be shown as `/users/:userId()` in Sentry. This will make it easier to identify patterns and make grouping easier.

### Other Changes

- feat(astro): Deprecate passing runtime config to astro integration ([#16839](https://github.com/getsentry/sentry-javascript/pull/16839))
- feat(browser): Add `beforeStartNavigationSpan` lifecycle hook ([#16863](https://github.com/getsentry/sentry-javascript/pull/16863))
Copy link
Member

Choose a reason for hiding this comment

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

l: Maybe we should highlight this as an important change and add a snippet for how to use it, wdyt?

Copy link
Member Author

Choose a reason for hiding this comment

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

@Lms24 I am not sure here but I think those hooks are mainly meant for our SDK internally?

Copy link
Member

Choose a reason for hiding this comment

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

yes, they're internally mostly. no need for an important change

- feat(browser): Detect redirects when emitting navigation spans ([#16324](https://github.com/getsentry/sentry-javascript/pull/16324))
- feat(cloudflare): Add option to opt out of capturing errors in `wrapRequestHandler` ([#16852](https://github.com/getsentry/sentry-javascript/pull/16852))
- feat(feedback): Return the eventId into the onSubmitSuccess callback ([#16835](https://github.com/getsentry/sentry-javascript/pull/16835))
- feat(vercel-edge): Do not vendor in all OpenTelemetry dependencies ([#16841](https://github.com/getsentry/sentry-javascript/pull/16841))
- fix(browser): Ensure standalone CLS and LCP spans have traceId of pageload span ([#16864](https://github.com/getsentry/sentry-javascript/pull/16864))
- fix(nextjs): Use value injection loader on `instrumentation-client.ts|js` ([#16855](https://github.com/getsentry/sentry-javascript/pull/16855))
- fix(sveltekit): Avoid capturing `redirect()` calls as errors in Cloudflare ([#16853](https://github.com/getsentry/sentry-javascript/pull/16853))
- docs(nextjs): Update `deleteSourcemapsAfterUpload` jsdoc default value ([#16867](https://github.com/getsentry/sentry-javascript/pull/16867))

Work in this release was contributed by @zachkirsch. Thank you for your contribution!
Comment on lines +27 to +29
Copy link
Member Author

Choose a reason for hiding this comment

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

Usually, we don't list docs PRs but this was added by an external contribution so I left it here.

Copy link
Member

Choose a reason for hiding this comment

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

I think we can remove the entry but keep the attribution, but no strong opinion


## 9.36.0

### Important Changes
Expand Down
3 changes: 2 additions & 1 deletion dev-packages/browser-integration-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@
"test:detect-flaky": "ts-node scripts/detectFlakyTests.ts"
},
"dependencies": {
"@babel/core": "^7.27.7",
"@babel/preset-typescript": "^7.16.7",
"@playwright/test": "~1.50.0",
"@playwright/test": "~1.53.2",
"@sentry-internal/rrweb": "2.34.0",
"@sentry/browser": "9.36.0",
"@supabase/supabase-js": "2.49.3",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,4 @@ window.Sentry = Sentry;

Sentry.init({
dsn: 'https://[email protected]/1337',
transportOptions: {
fetchOptions: {
// See: https://github.com/microsoft/playwright/issues/34497
keepalive: false,
},
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,4 @@ window.Sentry = Sentry;

Sentry.init({
dsn: 'https://[email protected]/1337',
transportOptions: {
fetchOptions: {
// See: https://github.com/microsoft/playwright/issues/34497
keepalive: false,
},
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,4 @@ Sentry.init({
}),
],
tracesSampleRate: 1,
transportOptions: {
fetchOptions: {
// See: https://github.com/microsoft/playwright/issues/34497
keepalive: false,
},
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,4 @@ Sentry.init({
}),
],
tracesSampleRate: 1,
transportOptions: {
fetchOptions: {
// See: https://github.com/microsoft/playwright/issues/34497
keepalive: false,
},
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Sentry.init({
consistentTraceSampling: true,
}),
],
tracePropagationTargets: ['someurl.com'],
tracePropagationTargets: ['sentry-test-external.io'],
tracesSampler: ctx => {
if (ctx.attributes && ctx.attributes['sentry.origin'] === 'auto.pageload.browser') {
return 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ btn1.addEventListener('click', () => {
btn2.addEventListener('click', () => {
Sentry.startNewTrace(() => {
Sentry.startSpan({ name: 'custom root span 2', op: 'custom' }, async () => {
await fetch('https://someUrl.com');
await fetch('http://sentry-test-external.io');
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ sentryTest.describe('When `consistentTraceSampling` is `true`', () => {

await sentryTest.step('Make fetch request', async () => {
const fetchTracePromise = waitForTransactionRequest(page, evt => evt.contexts?.trace?.op === 'custom');
const tracingHeadersPromise = waitForTracingHeadersOnUrl(page, 'https://someUrl.com');
const tracingHeadersPromise = waitForTracingHeadersOnUrl(page, 'http://sentry-test-external.io');

await page.locator('#btn2').click();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Sentry.init({
consistentTraceSampling: true,
}),
],
tracePropagationTargets: ['someurl.com'],
tracePropagationTargets: ['sentry-test-external.io'],
tracesSampleRate: 1,
debug: true,
sendClientReports: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ btn1.addEventListener('click', () => {
btn2.addEventListener('click', () => {
Sentry.startNewTrace(() => {
Sentry.startSpan({ name: 'custom root span 2', op: 'custom' }, async () => {
await fetch('https://someUrl.com');
await fetch('http://sentry-test-external.io');
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ sentryTest.describe('When `consistentTraceSampling` is `true` and page contains
});

await sentryTest.step('Make fetch request', async () => {
const tracingHeadersPromise = waitForTracingHeadersOnUrl(page, 'https://someUrl.com');
const tracingHeadersPromise = waitForTracingHeadersOnUrl(page, 'http://sentry-test-external.io');

await page.locator('#btn2').click();
const { baggage, sentryTrace } = await tracingHeadersPromise;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Sentry.init({
consistentTraceSampling: true,
}),
],
tracePropagationTargets: ['someurl.com'],
tracePropagationTargets: ['sentry-test-external.io'],
tracesSampler: ({ inheritOrSampleWith }) => {
return inheritOrSampleWith(0);
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ btn1?.addEventListener('click', () => {
btn2?.addEventListener('click', () => {
Sentry.startNewTrace(() => {
Sentry.startSpan({ name: 'custom root span 2', op: 'custom' }, async () => {
await fetch('https://someUrl.com');
await fetch('http://sentry-test-external.io');
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ sentryTest.describe('When `consistentTraceSampling` is `true` and page contains
sentryTest.skip();
}




const url = await getLocalTestUrl({ testDir: __dirname });

const clientReportPromise = waitForClientReportRequest(page);
Expand All @@ -34,7 +37,7 @@ sentryTest.describe('When `consistentTraceSampling` is `true` and page contains
});

await sentryTest.step('Make fetch request', async () => {
const tracingHeadersPromise = waitForTracingHeadersOnUrl(page, 'https://someUrl.com');
const tracingHeadersPromise = waitForTracingHeadersOnUrl(page, 'http://sentry-test-external.io');

await page.locator('#btn2').click();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Sentry.init({
consistentTraceSampling: true,
}),
],
tracePropagationTargets: ['someurl.com'],
tracePropagationTargets: ['sentry-test-external.io'],
// only take into account sampling from meta tag; otherwise sample negatively
tracesSampleRate: 0,
debug: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ btn1.addEventListener('click', () => {
btn2.addEventListener('click', () => {
Sentry.startNewTrace(() => {
Sentry.startSpan({ name: 'custom root span 2', op: 'custom' }, async () => {
await fetch('https://someUrl.com');
await fetch('http://sentry-test-external.io');
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ sentryTest.describe('When `consistentTraceSampling` is `true` and page contains

await sentryTest.step('Make fetch request', async () => {
const fetchTracePromise = waitForTransactionRequest(page, evt => evt.contexts?.trace?.op === 'custom');
const tracingHeadersPromise = waitForTracingHeadersOnUrl(page, 'https://someUrl.com');
const tracingHeadersPromise = waitForTracingHeadersOnUrl(page, 'http://sentry-test-external.io');

await page.locator('#btn2').click();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Sentry.init({
enableInp: false,
}),
],
tracePropagationTargets: ['someurl.com'],
tracePropagationTargets: ['sentry-test-external.io'],
tracesSampler: ctx => {
if (ctx.attributes && ctx.attributes['sentry.origin'] === 'auto.pageload.browser') {
return 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ btn1.addEventListener('click', () => {
btn2.addEventListener('click', () => {
Sentry.startNewTrace(() => {
Sentry.startSpan({ name: 'custom root span 2', op: 'custom' }, async () => {
await fetch('https://someUrl.com');
await fetch('http://sentry-test-external.io');
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ window.Sentry = Sentry;

Sentry.init({
dsn: 'https://[email protected]/1337',
integrations: [Sentry.browserTracingIntegration()],
// We want to ignore redirects for this test
integrations: [Sentry.browserTracingIntegration({ detectRedirects: false })],
tracesSampler: ctx => {
if (ctx.attributes['sentry.origin'] === 'auto.pageload.browser') {
return 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ window.Sentry = Sentry;

Sentry.init({
dsn: 'https://[email protected]/1337',
integrations: [Sentry.browserTracingIntegration()],
integrations: [Sentry.browserTracingIntegration({ idleTimeout: 2000 })],
tracesSampleRate: 1,
});

// Immediately navigate to a new page to abort the pageload
window.history.pushState({}, '', '/sub-page');
// Navigate to a new page to abort the pageload
// We have to wait >300ms to avoid the redirect handling
setTimeout(() => {
window.history.pushState({}, '', '/sub-page');
}, 500);
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import * as Sentry from '@sentry/browser';

window.Sentry = Sentry;

Sentry.init({
dsn: 'https://[email protected]/1337',
integrations: [Sentry.browserTracingIntegration()],
tracesSampleRate: 1,
debug: true,
});

document.getElementById('btn1').addEventListener('click', () => {
// Trigger navigation later than click, so the last click is more than 300ms ago
setTimeout(() => {
window.history.pushState({}, '', '/sub-page');

// then trigger redirect inside of this navigation, which should be detected as a redirect
// because the last click was more than 300ms ago
setTimeout(() => {
window.history.pushState({}, '', '/sub-page-redirect');
}, 100);
}, 400);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
</head>
<button id="btn1">Trigger navigation</button>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { expect } from '@playwright/test';
import { sentryTest } from '../../../../../utils/fixtures';
import { envelopeRequestParser, shouldSkipTracingTest, waitForTransactionRequest } from '../../../../../utils/helpers';

sentryTest(
'should create a navigation.redirect span if a click happened more than 300ms before navigation',
async ({ getLocalTestUrl, page }) => {
if (shouldSkipTracingTest()) {
sentryTest.skip();
}

const url = await getLocalTestUrl({ testDir: __dirname });

const pageloadRequestPromise = waitForTransactionRequest(page, event => event.contexts?.trace?.op === 'pageload');
const navigationRequestPromise = waitForTransactionRequest(
page,
event => event.contexts?.trace?.op === 'navigation',
);

await page.goto(url);

await pageloadRequestPromise;

// Now trigger navigation, and then a redirect in the navigation, with
await page.click('#btn1');

const navigationRequest = envelopeRequestParser(await navigationRequestPromise);

expect(navigationRequest.contexts?.trace?.op).toBe('navigation');
expect(navigationRequest.transaction).toEqual('/sub-page');

const spans = navigationRequest.spans || [];

expect(spans).toContainEqual(
expect.objectContaining({
op: 'navigation.redirect',
description: '/sub-page-redirect',
}),
);
},
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import * as Sentry from '@sentry/browser';

window.Sentry = Sentry;

Sentry.init({
dsn: 'https://[email protected]/1337',
integrations: [Sentry.browserTracingIntegration()],
tracesSampleRate: 1,
debug: true,
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
document.getElementById('btn1').addEventListener('click', () => {
// trigger redirect immediately
window.history.pushState({}, '', '/sub-page');
});

// Now trigger click, which should trigger navigation
document.getElementById('btn1').click();
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
</head>
<button id="btn1" type="button">Trigger navigation</button>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { expect } from '@playwright/test';
import { sentryTest } from '../../../../../utils/fixtures';
import { envelopeRequestParser, shouldSkipTracingTest, waitForTransactionRequest } from '../../../../../utils/helpers';

sentryTest(
'should not create a navigation.redirect span if a click happened before navigation',
async ({ getLocalTestUrl, page }) => {
if (shouldSkipTracingTest()) {
sentryTest.skip();
}

const url = await getLocalTestUrl({ testDir: __dirname });

const pageloadRequestPromise = waitForTransactionRequest(page, event => event.contexts?.trace?.op === 'pageload');
const navigationRequestPromise = waitForTransactionRequest(
page,
event => event.contexts?.trace?.op === 'navigation',
);

await page.goto(url);

const pageloadRequest = envelopeRequestParser(await pageloadRequestPromise);
// Ensure a navigation span is sent, too
await navigationRequestPromise;

const spans = pageloadRequest.spans || [];

expect(spans).not.toContainEqual(
expect.objectContaining({
op: 'navigation.redirect',
}),
);
},
);
Loading
Loading