From 7c5c438ff3a60d5543ea118efaf9be1dcfe75918 Mon Sep 17 00:00:00 2001 From: Nicolas Hrubec Date: Thu, 23 Apr 2026 14:10:40 +0200 Subject: [PATCH 1/2] implement --- .../integrations/httpContext-streamed/init.js | 9 +++++++ .../integrations/httpContext-streamed/test.ts | 27 +++++++++++++++++++ .../public-api/startSpan/streamed/test.ts | 8 ++++++ .../interactions-streamed/test.ts | 8 ++++++ .../navigation-streamed/test.ts | 8 ++++++ .../pageload-streamed/test.ts | 8 ++++++ .../browser/src/integrations/httpcontext.ts | 15 +++++++++++ 7 files changed, 83 insertions(+) create mode 100644 dev-packages/browser-integration-tests/suites/integrations/httpContext-streamed/init.js create mode 100644 dev-packages/browser-integration-tests/suites/integrations/httpContext-streamed/test.ts diff --git a/dev-packages/browser-integration-tests/suites/integrations/httpContext-streamed/init.js b/dev-packages/browser-integration-tests/suites/integrations/httpContext-streamed/init.js new file mode 100644 index 000000000000..c69a872adc77 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/integrations/httpContext-streamed/init.js @@ -0,0 +1,9 @@ +import * as Sentry from '@sentry/browser'; + +window.Sentry = Sentry; + +Sentry.init({ + dsn: 'https://public@dsn.ingest.sentry.io/1337', + integrations: [Sentry.spanStreamingIntegration(), Sentry.browserTracingIntegration()], + tracesSampleRate: 1.0, +}); diff --git a/dev-packages/browser-integration-tests/suites/integrations/httpContext-streamed/test.ts b/dev-packages/browser-integration-tests/suites/integrations/httpContext-streamed/test.ts new file mode 100644 index 000000000000..cb1e88072a9f --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/integrations/httpContext-streamed/test.ts @@ -0,0 +1,27 @@ +import { expect } from '@playwright/test'; +import { sentryTest } from '../../../utils/fixtures'; +import { shouldSkipTracingTest } from '../../../utils/helpers'; +import { getSpanOp, waitForStreamedSpans } from '../../../utils/spanUtils'; + +sentryTest('httpContextIntegration captures url, user-agent, and referer', async ({ getLocalTestUrl, page }) => { + sentryTest.skip(shouldSkipTracingTest()); + const url = await getLocalTestUrl({ testDir: __dirname }); + + const spansPromise = waitForStreamedSpans(page, spans => spans.some(s => getSpanOp(s) === 'pageload')); + + await page.goto(url, { referer: 'https://sentry.io/' }); + + const spans = await spansPromise; + + const pageloadSpan = spans.find(s => getSpanOp(s) === 'pageload'); + + expect(pageloadSpan!.attributes?.['url.full']).toEqual({ type: 'string', value: expect.any(String) }); + expect(pageloadSpan!.attributes?.['http.request.header.user_agent']).toEqual({ + type: 'string', + value: expect.any(String), + }); + expect(pageloadSpan!.attributes?.['http.request.header.referer']).toEqual({ + type: 'string', + value: 'https://sentry.io/', + }); +}); diff --git a/dev-packages/browser-integration-tests/suites/public-api/startSpan/streamed/test.ts b/dev-packages/browser-integration-tests/suites/public-api/startSpan/streamed/test.ts index 7a70c832558f..ba4e492c9f26 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/startSpan/streamed/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/startSpan/streamed/test.ts @@ -179,6 +179,14 @@ sentryTest( type: 'string', value: expect.any(String), }, + 'http.request.header.user_agent': { + type: 'string', + value: expect.any(String), + }, + 'url.full': { + type: 'string', + value: expect.any(String), + }, [SEMANTIC_ATTRIBUTE_SENTRY_OP]: { type: 'string', value: 'test', diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/interactions-streamed/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/interactions-streamed/test.ts index f1b0882d2325..383ecade3530 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/interactions-streamed/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/interactions-streamed/test.ts @@ -52,6 +52,14 @@ sentryTest('captures streamed interaction span tree. @firefox', async ({ browser type: 'string', value: expect.any(String), }, + 'http.request.header.user_agent': { + type: 'string', + value: expect.any(String), + }, + 'url.full': { + type: 'string', + value: expect.any(String), + }, [SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON]: { type: 'string', value: 'idleTimeout', diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/navigation-streamed/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/navigation-streamed/test.ts index 520a3d330bb9..c2dcad317a3f 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/navigation-streamed/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/navigation-streamed/test.ts @@ -81,6 +81,14 @@ sentryTest('starts a streamed navigation span on page navigation', async ({ brow type: 'string', value: expect.any(String), }, + 'http.request.header.user_agent': { + type: 'string', + value: expect.any(String), + }, + 'url.full': { + type: 'string', + value: expect.any(String), + }, 'device.processor_count': { type: expect.stringMatching(/^(integer)|(double)$/), value: expect.any(Number), diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-streamed/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-streamed/test.ts index 6b09fcd0097d..2344e28c67d4 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-streamed/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-streamed/test.ts @@ -74,6 +74,14 @@ sentryTest( type: 'string', value: expect.any(String), }, + 'http.request.header.user_agent': { + type: 'string', + value: expect.any(String), + }, + 'url.full': { + type: 'string', + value: expect.any(String), + }, // formerly known as 'hardwareConcurrency' 'device.processor_count': { type: expect.stringMatching(/^(integer)|(double)$/), diff --git a/packages/browser/src/integrations/httpcontext.ts b/packages/browser/src/integrations/httpcontext.ts index 9517b2364e83..e651273ba74d 100644 --- a/packages/browser/src/integrations/httpcontext.ts +++ b/packages/browser/src/integrations/httpcontext.ts @@ -26,5 +26,20 @@ export const httpContextIntegration = defineIntegration(() => { headers, }; }, + processSegmentSpan(span) { + // if none of the information we want exists, don't bother + if (!WINDOW.navigator && !WINDOW.location && !WINDOW.document) { + return; + } + + const reqData = getHttpRequestData(); + + span.attributes = { + 'url.full': reqData.url, + 'http.request.header.user_agent': reqData.headers['User-Agent'], + 'http.request.header.referer': reqData.headers['Referer'], + ...span.attributes, + }; + }, }; }); From c0c0158084965914722fe5f3c9840a996d5b2c2e Mon Sep 17 00:00:00 2001 From: Nicolas Hrubec Date: Thu, 23 Apr 2026 15:17:01 +0200 Subject: [PATCH 2/2] bump size limits --- .size-limit.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.size-limit.js b/.size-limit.js index cad516a0a49a..5ccee07ac526 100644 --- a/.size-limit.js +++ b/.size-limit.js @@ -59,7 +59,7 @@ module.exports = [ path: 'packages/browser/build/npm/esm/prod/index.js', import: createImport('init', 'browserTracingIntegration', 'replayIntegration'), gzip: true, - limit: '83 KB', + limit: '84 KB', }, { name: '@sentry/browser (incl. Tracing, Replay) - with treeshaking flags', @@ -138,7 +138,7 @@ module.exports = [ path: 'packages/browser/build/npm/esm/prod/index.js', import: createImport('init', 'metrics', 'logger'), gzip: true, - limit: '28 KB', + limit: '29 KB', }, // React SDK (ESM) { @@ -197,7 +197,7 @@ module.exports = [ name: 'CDN Bundle (incl. Logs, Metrics)', path: createCDNPath('bundle.logs.metrics.min.js'), gzip: true, - limit: '30 KB', + limit: '31 KB', }, { name: 'CDN Bundle (incl. Tracing, Logs, Metrics)', @@ -283,21 +283,21 @@ module.exports = [ path: createCDNPath('bundle.tracing.replay.logs.metrics.min.js'), gzip: false, brotli: false, - limit: '258.5 KB', + limit: '259 KB', }, { name: 'CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed', path: createCDNPath('bundle.tracing.replay.feedback.min.js'), gzip: false, brotli: false, - limit: '268 KB', + limit: '269 KB', }, { name: 'CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed', path: createCDNPath('bundle.tracing.replay.feedback.logs.metrics.min.js'), gzip: false, brotli: false, - limit: '271.5 KB', + limit: '272 KB', }, // Next.js SDK (ESM) {