Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
9a016ca
Merge pull request #18527 from getsentry/master
github-actions[bot] Dec 16, 2025
99183a7
feat(nextjs): added webpack treeshaking flags as config (#18359)
logaretm Dec 16, 2025
4be48a6
chore(deps): bump @trpc/server from 10.45.2 to 10.45.3 in /dev-packag…
dependabot[bot] Dec 17, 2025
a8cb0f6
feat(nextjs): Extract tracing logic from server component wrapper tem…
chargome Dec 17, 2025
191ed1d
test(cloudflare-mcp): Unpin mcp sdk (#18528)
JPeer264 Dec 17, 2025
f3fbcd9
feat(replay): Add Request body with `attachRawBodyFromRequest` option…
s1gr1d Dec 17, 2025
816b8e3
chore(github): Add "Closes" to PR template (#18538)
s1gr1d Dec 17, 2025
85b4812
chore(e2e): Remove check on `http.response_content_length_uncompresse…
andreiborza Dec 17, 2025
2c45b73
feat(tanstackstart-react): Trace server functions (#18500)
nicohrubec Dec 17, 2025
3d58496
feat(core): Capture initialize attributes on MCP servers (#18531)
betegon Dec 17, 2025
8b2c0c2
test(nextjs): Add e2e tests for server component spans in next 16 (#…
chargome Dec 17, 2025
ad28c4d
fix(solid/tanstackrouter): Ensure web vitals are sent on pageload (#…
logaretm Dec 17, 2025
97e0be0
chore(e2e): Pin to react-router 7.10.1 in spa e2e test (#18548)
andreiborza Dec 17, 2025
968e529
feat(vue): Add TanStack Router integration (#18547)
andreiborza Dec 17, 2025
8da7295
feat(core): Apply scope attributes to logs (#18184)
Lms24 Dec 18, 2025
ea3a45f
chore(changelog): Add entry for scope attributes (#18555)
Lms24 Dec 18, 2025
f196ba2
chore(deps): bump @trpc/server from 10.45.2 to 10.45.3 in /dev-packag…
dependabot[bot] Dec 18, 2025
dac328a
chore(changelog): Add entry for tanstack start wrapFetchWithSentry (#…
nicohrubec Dec 18, 2025
b21806c
meta(changelog): Update changelog for 10.32.0
andreiborza Dec 18, 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
3 changes: 3 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@ Before submitting a pull request, please take a look at our

- [ ] If you've added code that should be tested, please add tests.
- [ ] Ensure your code lints and the test suite passes (`yarn lint`) & (`yarn test`).
- [ ] Link an issue if there is one related to your pull request. If no issue is linked, one will be auto-generated and linked.

Closes #issue_link_here
6 changes: 3 additions & 3 deletions .size-limit.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ module.exports = [
path: 'packages/browser/build/npm/esm/prod/index.js',
import: createImport('init', 'browserTracingIntegration', 'replayIntegration'),
gzip: true,
limit: '80 KB',
limit: '82 KB',
},
{
name: '@sentry/browser (incl. Tracing, Replay) - with treeshaking flags',
Expand Down Expand Up @@ -89,7 +89,7 @@ module.exports = [
path: 'packages/browser/build/npm/esm/prod/index.js',
import: createImport('init', 'browserTracingIntegration', 'replayIntegration', 'feedbackIntegration'),
gzip: true,
limit: '97 KB',
limit: '98 KB',
},
{
name: '@sentry/browser (incl. Feedback)',
Expand Down Expand Up @@ -213,7 +213,7 @@ module.exports = [
import: createImport('init'),
ignore: ['next/router', 'next/constants'],
gzip: true,
limit: '46 KB',
limit: '46.5 KB',
},
// SvelteKit SDK (ESM)
{
Expand Down
99 changes: 99 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,105 @@

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

## 10.32.0

### Important Changes

- **feat(core): Apply scope attributes to logs ([#18184](https://github.com/getsentry/sentry-javascript/pull/18184))**

You can now set attributes on the SDK's scopes which will be applied to all logs as long as the respective scopes are active. For the time being, only `string`, `number` and `boolean` attribute values are supported.

```ts
Sentry.geGlobalScope().setAttributes({ is_admin: true, auth_provider: 'google' });

Sentry.withScope(scope => {
scope.setAttribute('step', 'authentication');

// scope attributes `is_admin`, `auth_provider` and `step` are added
Sentry.logger.info(`user ${user.id} logged in`, { activeSince: 100 });
Sentry.logger.info(`updated ${user.id} last activity`);
});

// scope attributes `is_admin` and `auth_provider` are added
Sentry.logger.warn('stale website version, reloading page');
```

- **feat(replay): Add Request body with `attachRawBodyFromRequest` option ([#18501](https://github.com/getsentry/sentry-javascript/pull/18501))**

To attach the raw request body (from `Request` objects passed as the first `fetch` argument) to replay events, you can now use the `attachRawBodyFromRequest` option in the Replay integration:

```js
Sentry.init({
integrations: [
Sentry.replayIntegration({
attachRawBodyFromRequest: true,
}),
],
});
```

- **feat(tanstackstart-react): Trace server functions ([#18500](https://github.com/getsentry/sentry-javascript/pull/18500))**

To enable tracing for server-side requests, you can now explicitly define a [server entry point](https://tanstack.com/start/latest/docs/framework/react/guide/server-entry-point) in your application and wrap your request handler with `wrapFetchWithSentry`.

```typescript
// src/server.ts
import { wrapFetchWithSentry } from '@sentry/tanstackstart-react';
import handler, { createServerEntry } from '@tanstack/react-start/server-entry';

export default createServerEntry(
wrapFetchWithSentry({
fetch(request: Request) {
return handler.fetch(request);
},
}),
);
```

- **feat(vue): Add TanStack Router integration ([#18547](https://github.com/getsentry/sentry-javascript/pull/18547))**

The `@sentry/vue` package now includes support for TanStack Router. Use `tanstackRouterBrowserTracingIntegration` to automatically instrument pageload and navigation transactions with parameterized routes:

```javascript
import { createApp } from 'vue';
import { createRouter } from '@tanstack/vue-router';
import * as Sentry from '@sentry/vue';
import { tanstackRouterBrowserTracingIntegration } from '@sentry/vue/tanstackrouter';

const router = createRouter({
// your router config
});

Sentry.init({
app,
dsn: '__PUBLIC_DSN__',
integrations: [tanstackRouterBrowserTracingIntegration(router)],
tracesSampleRate: 1.0,
});
```

### Other Changes

- feat(core): Capture initialize attributes on MCP servers ([#18531](https://github.com/getsentry/sentry-javascript/pull/18531))
- feat(nextjs): Extract tracing logic from server component wrapper templates ([#18408](https://github.com/getsentry/sentry-javascript/pull/18408))
- feat(nextjs): added webpack treeshaking flags as config ([#18359](https://github.com/getsentry/sentry-javascript/pull/18359))
- fix(solid/tanstackrouter): Ensure web vitals are sent on pageload ([#18542](https://github.com/getsentry/sentry-javascript/pull/18542))

<details>
<summary> <strong>Internal Changes</strong> </summary>

- chore(changelog): Add entry for scope attributes ([#18555](https://github.com/getsentry/sentry-javascript/pull/18555))
- chore(changelog): Add entry for tanstack start wrapFetchWithSentry ([#18558](https://github.com/getsentry/sentry-javascript/pull/18558))
- chore(deps): bump @trpc/server from 10.45.2 to 10.45.3 in /dev-packages/e2e-tests/test-applications/node-express-incorrect-instrumentation ([#18530](https://github.com/getsentry/sentry-javascript/pull/18530))
- chore(deps): bump @trpc/server from 10.45.2 to 10.45.3 in /dev-packages/e2e-tests/test-applications/node-express-v5 ([#18550](https://github.com/getsentry/sentry-javascript/pull/18550))
- chore(e2e): Pin to react-router 7.10.1 in spa e2e test ([#18548](https://github.com/getsentry/sentry-javascript/pull/18548))
- chore(e2e): Remove check on `http.response_content_length_uncompressed` ([#18536](https://github.com/getsentry/sentry-javascript/pull/18536))
- chore(github): Add "Closes" to PR template ([#18538](https://github.com/getsentry/sentry-javascript/pull/18538))
- test(cloudflare-mcp): Unpin mcp sdk ([#18528](https://github.com/getsentry/sentry-javascript/pull/18528))
- test(nextjs): Add e2e tests for server component spans in next 16 ([#18544](https://github.com/getsentry/sentry-javascript/pull/18544))

</details>

## 10.31.0

### Important Changes
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { expect } from '@playwright/test';
import type { LogEnvelope } from '@sentry/core';
import { sentryTest } from '../../../../utils/fixtures';
import { getFirstSentryEnvelopeRequest, properFullEnvelopeRequestParser } from '../../../../utils/helpers';
import {
getFirstSentryEnvelopeRequest,
properFullEnvelopeRequestParser,
testingCdnBundle,
} from '../../../../utils/helpers';

sentryTest('should capture console object calls', async ({ getLocalTestUrl, page }) => {
const bundle = process.env.PW_BUNDLE || '';
// Only run this for npm package exports
if (bundle.startsWith('bundle') || bundle.startsWith('loader')) {
sentryTest.skip();
}
sentryTest.skip(testingCdnBundle());

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

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// only log attribute
Sentry.logger.info('log_before_any_scope', { log_attr: 'log_attr_1' });

Sentry.getGlobalScope().setAttributes({ global_scope_attr: true });

// this attribute will not be sent for now
Sentry.getGlobalScope().setAttribute('array_attr', [1, 2, 3]);

// global scope, log attribute
Sentry.logger.info('log_after_global_scope', { log_attr: 'log_attr_2' });

Sentry.withIsolationScope(isolationScope => {
isolationScope.setAttribute('isolation_scope_1_attr', { value: 100, unit: 'millisecond' });

// global scope, isolation scope, log attribute
Sentry.logger.info('log_with_isolation_scope', { log_attr: 'log_attr_3' });

Sentry.withScope(scope => {
scope.setAttributes({ scope_attr: { value: 200, unit: 'millisecond' } });

// global scope, isolation scope, current scope attribute, log attribute
Sentry.logger.info('log_with_scope', { log_attr: 'log_attr_4' });
});

Sentry.withScope(scope2 => {
scope2.setAttribute('scope_2_attr', { value: 300, unit: 'millisecond' });

// global scope, isolation scope, current scope attribute, log attribute
Sentry.logger.info('log_with_scope_2', { log_attr: 'log_attr_5' });
});
});

Sentry.flush();
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { expect } from '@playwright/test';
import type { LogEnvelope } from '@sentry/core';
import { sentryTest } from '../../../../utils/fixtures';
import {
getFirstSentryEnvelopeRequest,
properFullEnvelopeRequestParser,
testingCdnBundle,
} from '../../../../utils/helpers';

sentryTest('captures logs with scope attributes', async ({ getLocalTestUrl, page }) => {
sentryTest.skip(testingCdnBundle());

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

const event = await getFirstSentryEnvelopeRequest<LogEnvelope>(page, url, properFullEnvelopeRequestParser);
const envelopeItems = event[1];

expect(envelopeItems[0]).toEqual([
{
type: 'log',
item_count: 5,
content_type: 'application/vnd.sentry.items.log+json',
},
{
items: [
{
timestamp: expect.any(Number),
level: 'info',
body: 'log_before_any_scope',
severity_number: 9,
trace_id: expect.any(String),
attributes: {
'sentry.sdk.name': { value: 'sentry.javascript.browser', type: 'string' },
'sentry.sdk.version': { value: expect.any(String), type: 'string' },
log_attr: { value: 'log_attr_1', type: 'string' },
},
},
{
timestamp: expect.any(Number),
level: 'info',
body: 'log_after_global_scope',
severity_number: 9,
trace_id: expect.any(String),
attributes: {
'sentry.sdk.name': { value: 'sentry.javascript.browser', type: 'string' },
'sentry.sdk.version': { value: expect.any(String), type: 'string' },
global_scope_attr: { value: true, type: 'boolean' },
log_attr: { value: 'log_attr_2', type: 'string' },
},
},
{
timestamp: expect.any(Number),
level: 'info',
body: 'log_with_isolation_scope',
severity_number: 9,
trace_id: expect.any(String),
attributes: {
'sentry.sdk.name': { value: 'sentry.javascript.browser', type: 'string' },
'sentry.sdk.version': { value: expect.any(String), type: 'string' },
global_scope_attr: { value: true, type: 'boolean' },
isolation_scope_1_attr: { value: 100, unit: 'millisecond', type: 'integer' },
log_attr: { value: 'log_attr_3', type: 'string' },
},
},
{
timestamp: expect.any(Number),
level: 'info',
body: 'log_with_scope',
severity_number: 9,
trace_id: expect.any(String),
attributes: {
'sentry.sdk.name': { value: 'sentry.javascript.browser', type: 'string' },
'sentry.sdk.version': { value: expect.any(String), type: 'string' },
global_scope_attr: { value: true, type: 'boolean' },
isolation_scope_1_attr: { value: 100, unit: 'millisecond', type: 'integer' },
scope_attr: { value: 200, unit: 'millisecond', type: 'integer' },
log_attr: { value: 'log_attr_4', type: 'string' },
},
},
{
timestamp: expect.any(Number),
level: 'info',
body: 'log_with_scope_2',
severity_number: 9,
trace_id: expect.any(String),
attributes: {
'sentry.sdk.name': { value: 'sentry.javascript.browser', type: 'string' },
'sentry.sdk.version': { value: expect.any(String), type: 'string' },
global_scope_attr: { value: true, type: 'boolean' },
isolation_scope_1_attr: { value: 100, unit: 'millisecond', type: 'integer' },
scope_2_attr: { value: 300, unit: 'millisecond', type: 'integer' },
log_attr: { value: 'log_attr_5', type: 'string' },
},
},
],
},
]);
});
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { expect } from '@playwright/test';
import type { LogEnvelope } from '@sentry/core';
import { sentryTest } from '../../../../utils/fixtures';
import { getFirstSentryEnvelopeRequest, properFullEnvelopeRequestParser } from '../../../../utils/helpers';
import {
getFirstSentryEnvelopeRequest,
properFullEnvelopeRequestParser,
testingCdnBundle,
} from '../../../../utils/helpers';

sentryTest('should capture all logging methods', async ({ getLocalTestUrl, page }) => {
const bundle = process.env.PW_BUNDLE || '';
// Only run this for npm package exports
if (bundle.startsWith('bundle') || bundle.startsWith('loader')) {
sentryTest.skip();
}
sentryTest.skip(testingCdnBundle());

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

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import * as Sentry from '@sentry/browser';

window.Sentry = Sentry;
window.Replay = Sentry.replayIntegration({
flushMinDelay: 200,
flushMaxDelay: 200,
minReplayDuration: 0,

networkDetailAllowUrls: ['http://sentry-test.io/foo'],
networkCaptureBodies: true,
attachRawBodyFromRequest: true,
});

Sentry.init({
dsn: 'https://[email protected]/1337',
sampleRate: 1,
// We ensure to sample for errors, so by default nothing is sent
replaysSessionSampleRate: 0.0,
replaysOnErrorSampleRate: 1.0,

integrations: [window.Replay],
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h1>attachRawBodyFromRequest Test</h1>
</body>
</html>

Loading
Loading