From 38d6a1528b8482c4a43bdfb9ffe2f4458b9142af Mon Sep 17 00:00:00 2001 From: JPeer264 Date: Tue, 27 Jan 2026 13:05:20 +0100 Subject: [PATCH 1/5] feat(browser): Add mode option for the browser session integration --- .../suites/sessions/navigation-mode/init.js | 8 ++++ .../sessions/navigation-mode/subject.js | 6 +++ .../sessions/navigation-mode/template.html | 9 ++++ .../suites/sessions/navigation-mode/test.ts | 24 ++++++++++ .../suites/sessions/single-mode/init.js | 9 ++++ .../suites/sessions/single-mode/subject.js | 7 +++ .../suites/sessions/single-mode/template.html | 9 ++++ .../suites/sessions/single-mode/test.ts | 45 +++++++++++++++++++ packages/browser/src/index.ts | 1 + .../src/integrations/browsersession.ts | 37 +++++++++++---- 10 files changed, 146 insertions(+), 9 deletions(-) create mode 100644 dev-packages/browser-integration-tests/suites/sessions/navigation-mode/init.js create mode 100644 dev-packages/browser-integration-tests/suites/sessions/navigation-mode/subject.js create mode 100644 dev-packages/browser-integration-tests/suites/sessions/navigation-mode/template.html create mode 100644 dev-packages/browser-integration-tests/suites/sessions/navigation-mode/test.ts create mode 100644 dev-packages/browser-integration-tests/suites/sessions/single-mode/init.js create mode 100644 dev-packages/browser-integration-tests/suites/sessions/single-mode/subject.js create mode 100644 dev-packages/browser-integration-tests/suites/sessions/single-mode/template.html create mode 100644 dev-packages/browser-integration-tests/suites/sessions/single-mode/test.ts diff --git a/dev-packages/browser-integration-tests/suites/sessions/navigation-mode/init.js b/dev-packages/browser-integration-tests/suites/sessions/navigation-mode/init.js new file mode 100644 index 000000000000..af2df91a7ceb --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/sessions/navigation-mode/init.js @@ -0,0 +1,8 @@ +import * as Sentry from '@sentry/browser'; + +window.Sentry = Sentry; + +Sentry.init({ + dsn: 'https://public@dsn.ingest.sentry.io/1337', + release: '0.1', +}); diff --git a/dev-packages/browser-integration-tests/suites/sessions/navigation-mode/subject.js b/dev-packages/browser-integration-tests/suites/sessions/navigation-mode/subject.js new file mode 100644 index 000000000000..41f372c3aa79 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/sessions/navigation-mode/subject.js @@ -0,0 +1,6 @@ +let clickCount = 0; + +document.getElementById('navigate').addEventListener('click', () => { + clickCount++; + history.pushState({}, '', `/page-${clickCount}`); +}); diff --git a/dev-packages/browser-integration-tests/suites/sessions/navigation-mode/template.html b/dev-packages/browser-integration-tests/suites/sessions/navigation-mode/template.html new file mode 100644 index 000000000000..2a1b5d400981 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/sessions/navigation-mode/template.html @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/dev-packages/browser-integration-tests/suites/sessions/navigation-mode/test.ts b/dev-packages/browser-integration-tests/suites/sessions/navigation-mode/test.ts new file mode 100644 index 000000000000..a9ab937a1816 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/sessions/navigation-mode/test.ts @@ -0,0 +1,24 @@ +import { expect } from '@playwright/test'; +import type { SessionContext } from '@sentry/core'; +import { sentryTest } from '../../../utils/fixtures'; +import { getMultipleSentryEnvelopeRequests } from '../../../utils/helpers'; + +sentryTest('should start new sessions on pushState navigation in default mode.', async ({ getLocalTestUrl, page }) => { + const url = await getLocalTestUrl({ testDir: __dirname }); + + const sessionsPromise = getMultipleSentryEnvelopeRequests(page, 10, { + url, + envelopeType: 'session', + timeout: 4000, + }); + + await page.waitForSelector('#navigate'); + + await page.locator('#navigate').click(); + await page.locator('#navigate').click(); + await page.locator('#navigate').click(); + + const sessions = (await sessionsPromise).filter(session => session.init); + + expect(sessions.length).toBe(3); +}); diff --git a/dev-packages/browser-integration-tests/suites/sessions/single-mode/init.js b/dev-packages/browser-integration-tests/suites/sessions/single-mode/init.js new file mode 100644 index 000000000000..890a54f166eb --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/sessions/single-mode/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', + release: '0.1', + integrations: [Sentry.browserSessionIntegration({ mode: 'single' })], +}); diff --git a/dev-packages/browser-integration-tests/suites/sessions/single-mode/subject.js b/dev-packages/browser-integration-tests/suites/sessions/single-mode/subject.js new file mode 100644 index 000000000000..97a4037f17bb --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/sessions/single-mode/subject.js @@ -0,0 +1,7 @@ +let clickCount = 0; + +document.getElementById('navigate').addEventListener('click', () => { + clickCount++; + // Each click navigates to a different page + history.pushState({}, '', `/page-${clickCount}`); +}); diff --git a/dev-packages/browser-integration-tests/suites/sessions/single-mode/template.html b/dev-packages/browser-integration-tests/suites/sessions/single-mode/template.html new file mode 100644 index 000000000000..2a1b5d400981 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/sessions/single-mode/template.html @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/dev-packages/browser-integration-tests/suites/sessions/single-mode/test.ts b/dev-packages/browser-integration-tests/suites/sessions/single-mode/test.ts new file mode 100644 index 000000000000..c02c61eff450 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/sessions/single-mode/test.ts @@ -0,0 +1,45 @@ +import { expect } from '@playwright/test'; +import type { SessionContext } from '@sentry/core'; +import { sentryTest } from '../../../utils/fixtures'; +import { getMultipleSentryEnvelopeRequests } from '../../../utils/helpers'; + +sentryTest('should start a session on pageload in single mode.', async ({ getLocalTestUrl, page }) => { + const url = await getLocalTestUrl({ testDir: __dirname }); + + const sessions = await getMultipleSentryEnvelopeRequests(page, 1, { + url, + envelopeType: 'session', + timeout: 2000, + }); + + expect(sessions.length).toBeGreaterThanOrEqual(1); + const session = sessions[0]; + expect(session).toBeDefined(); + expect(session.init).toBe(true); + expect(session.errors).toBe(0); + expect(session.status).toBe('ok'); +}); + +sentryTest( + 'should NOT start a new session on pushState navigation in single mode.', + async ({ getLocalTestUrl, page }) => { + const url = await getLocalTestUrl({ testDir: __dirname }); + + const sessionsPromise = getMultipleSentryEnvelopeRequests(page, 10, { + url, + envelopeType: 'session', + timeout: 4000, + }); + + await page.waitForSelector('#navigate'); + + await page.locator('#navigate').click(); + await page.locator('#navigate').click(); + await page.locator('#navigate').click(); + + const sessions = (await sessionsPromise).filter(session => session.init); + + expect(sessions.length).toBe(1); + expect(sessions[0].init).toBe(true); + }, +); diff --git a/packages/browser/src/index.ts b/packages/browser/src/index.ts index 6e7c54198edc..d24ec3cd63de 100644 --- a/packages/browser/src/index.ts +++ b/packages/browser/src/index.ts @@ -76,6 +76,7 @@ export { makeBrowserOfflineTransport } from './transports/offline'; export { browserProfilingIntegration } from './profiling/integration'; export { spotlightBrowserIntegration } from './integrations/spotlight'; export { browserSessionIntegration } from './integrations/browsersession'; +export type { BrowserSessionOptions } from './integrations/browsersession'; export { launchDarklyIntegration, buildLaunchDarklyFlagUsedHandler } from './integrations/featureFlags/launchdarkly'; export { openFeatureIntegration, OpenFeatureIntegrationHook } from './integrations/featureFlags/openfeature'; export { unleashIntegration } from './integrations/featureFlags/unleash'; diff --git a/packages/browser/src/integrations/browsersession.ts b/packages/browser/src/integrations/browsersession.ts index 78a9228e3b29..10b6e0fcc05e 100644 --- a/packages/browser/src/integrations/browsersession.ts +++ b/packages/browser/src/integrations/browsersession.ts @@ -3,13 +3,30 @@ import { addHistoryInstrumentationHandler } from '@sentry-internal/browser-utils import { DEBUG_BUILD } from '../debug-build'; import { WINDOW } from '../helpers'; +export interface BrowserSessionOptions { + /** + * Controls when sessions are created. + * + * - `'single'`: A session is created once when the page is loaded. Session is not + * updated on navigation. This is useful for webviews or single-page apps where + * URL changes should not trigger new sessions. + * - `'navigation'`: A session is created on page load and on every navigation. + * This is the default behavior. + * + * @default 'navigation' + */ + mode?: 'single' | 'navigation'; +} + /** * When added, automatically creates sessions which allow you to track adoption and crashes (crash free rate) in your Releases in Sentry. * More information: https://docs.sentry.io/product/releases/health/ * * Note: In order for session tracking to work, you need to set up Releases: https://docs.sentry.io/product/releases/ */ -export const browserSessionIntegration = defineIntegration(() => { +export const browserSessionIntegration = defineIntegration((options: BrowserSessionOptions = {}) => { + const mode = options.mode ?? 'navigation'; + return { name: 'BrowserSession', setupOnce() { @@ -26,14 +43,16 @@ export const browserSessionIntegration = defineIntegration(() => { startSession({ ignoreDuration: true }); captureSession(); - // We want to create a session for every navigation as well - addHistoryInstrumentationHandler(({ from, to }) => { - // Don't create an additional session for the initial route or if the location did not change - if (from !== undefined && from !== to) { - startSession({ ignoreDuration: true }); - captureSession(); - } - }); + if (mode === 'navigation') { + // We want to create a session for every navigation as well + addHistoryInstrumentationHandler(({ from, to }) => { + // Don't create an additional session for the initial route or if the location did not change + if (from !== undefined && from !== to) { + startSession({ ignoreDuration: true }); + captureSession(); + } + }); + } }, }; }); From e32b2e4703b44013443b643a73ff3a77783abd50 Mon Sep 17 00:00:00 2001 From: JPeer264 Date: Fri, 30 Jan 2026 10:51:51 +0100 Subject: [PATCH 2/5] feat: BrowserSessionIntegration available in CDN/bundle --- packages/browser/src/exports.ts | 1 + packages/browser/src/index.ts | 2 -- packages/browser/src/integrations/browsersession.ts | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/browser/src/exports.ts b/packages/browser/src/exports.ts index 9b733cff92bd..bf0de4783c5a 100644 --- a/packages/browser/src/exports.ts +++ b/packages/browser/src/exports.ts @@ -102,5 +102,6 @@ export { globalHandlersIntegration } from './integrations/globalhandlers'; export { httpContextIntegration } from './integrations/httpcontext'; export { linkedErrorsIntegration } from './integrations/linkederrors'; export { browserApiErrorsIntegration } from './integrations/browserapierrors'; +export { browserSessionIntegration } from './integrations/browsersession'; export { lazyLoadIntegration } from './utils/lazyLoadIntegration'; diff --git a/packages/browser/src/index.ts b/packages/browser/src/index.ts index d24ec3cd63de..db89b6110866 100644 --- a/packages/browser/src/index.ts +++ b/packages/browser/src/index.ts @@ -75,8 +75,6 @@ export type { Span, FeatureFlagsIntegration } from '@sentry/core'; export { makeBrowserOfflineTransport } from './transports/offline'; export { browserProfilingIntegration } from './profiling/integration'; export { spotlightBrowserIntegration } from './integrations/spotlight'; -export { browserSessionIntegration } from './integrations/browsersession'; -export type { BrowserSessionOptions } from './integrations/browsersession'; export { launchDarklyIntegration, buildLaunchDarklyFlagUsedHandler } from './integrations/featureFlags/launchdarkly'; export { openFeatureIntegration, OpenFeatureIntegrationHook } from './integrations/featureFlags/openfeature'; export { unleashIntegration } from './integrations/featureFlags/unleash'; diff --git a/packages/browser/src/integrations/browsersession.ts b/packages/browser/src/integrations/browsersession.ts index 10b6e0fcc05e..a4f0beb651d6 100644 --- a/packages/browser/src/integrations/browsersession.ts +++ b/packages/browser/src/integrations/browsersession.ts @@ -3,7 +3,7 @@ import { addHistoryInstrumentationHandler } from '@sentry-internal/browser-utils import { DEBUG_BUILD } from '../debug-build'; import { WINDOW } from '../helpers'; -export interface BrowserSessionOptions { +interface BrowserSessionOptions { /** * Controls when sessions are created. * From f300ff8f81a789b7449d5820b958391fb5f9f20e Mon Sep 17 00:00:00 2001 From: JPeer264 Date: Thu, 5 Feb 2026 09:13:39 +0100 Subject: [PATCH 3/5] test: Verify if only one session exists --- .../suites/sessions/single-mode/subject.js | 5 ++++ .../suites/sessions/single-mode/template.html | 1 + .../suites/sessions/single-mode/test.ts | 27 +++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/dev-packages/browser-integration-tests/suites/sessions/single-mode/subject.js b/dev-packages/browser-integration-tests/suites/sessions/single-mode/subject.js index 97a4037f17bb..11d2e4fd8ada 100644 --- a/dev-packages/browser-integration-tests/suites/sessions/single-mode/subject.js +++ b/dev-packages/browser-integration-tests/suites/sessions/single-mode/subject.js @@ -5,3 +5,8 @@ document.getElementById('navigate').addEventListener('click', () => { // Each click navigates to a different page history.pushState({}, '', `/page-${clickCount}`); }); + +document.getElementById('manual-session').addEventListener('click', () => { + Sentry.startSession(); + Sentry.captureException('Test error from manual session'); +}); diff --git a/dev-packages/browser-integration-tests/suites/sessions/single-mode/template.html b/dev-packages/browser-integration-tests/suites/sessions/single-mode/template.html index 2a1b5d400981..0677aeffb4a9 100644 --- a/dev-packages/browser-integration-tests/suites/sessions/single-mode/template.html +++ b/dev-packages/browser-integration-tests/suites/sessions/single-mode/template.html @@ -5,5 +5,6 @@ + diff --git a/dev-packages/browser-integration-tests/suites/sessions/single-mode/test.ts b/dev-packages/browser-integration-tests/suites/sessions/single-mode/test.ts index c02c61eff450..bed3fd856f64 100644 --- a/dev-packages/browser-integration-tests/suites/sessions/single-mode/test.ts +++ b/dev-packages/browser-integration-tests/suites/sessions/single-mode/test.ts @@ -31,6 +31,16 @@ sentryTest( timeout: 4000, }); + const manualSessionsPromise = getMultipleSentryEnvelopeRequests(page, 10, { + envelopeType: 'session', + timeout: 4000, + }); + + const eventsPromise = getMultipleSentryEnvelopeRequests(page, 10, { + envelopeType: 'event', + timeout: 4000, + }); + await page.waitForSelector('#navigate'); await page.locator('#navigate').click(); @@ -41,5 +51,22 @@ sentryTest( expect(sessions.length).toBe(1); expect(sessions[0].init).toBe(true); + + // teardown and verify if nothing else got sent + await page.locator('#manual-session').click(); + + const newSessions = (await manualSessionsPromise).filter(session => session.init); + const events = await eventsPromise; + + expect(newSessions.length).toBe(2); + expect(newSessions[0].init).toBe(true); + expect(newSessions[1].init).toBe(true); + expect(newSessions[1].sid).not.toBe(newSessions[0].sid); + expect(events).toEqual([ + expect.objectContaining({ + level: 'error', + message: 'Test error from manual session', + }), + ]); }, ); From 2484c0f730cff08bd633341bb08a4d310816dc73 Mon Sep 17 00:00:00 2001 From: JPeer264 Date: Thu, 5 Feb 2026 09:26:51 +0100 Subject: [PATCH 4/5] ref: mode -> lifecycle --- .../suites/sessions/navigation-mode/test.ts | 24 ----------------- .../{single-mode => page-lifecycle}/init.js | 2 +- .../subject.js | 0 .../template.html | 0 .../{single-mode => page-lifecycle}/test.ts | 4 +-- .../init.js | 0 .../subject.js | 0 .../template.html | 0 .../suites/sessions/route-lifecycle/test.ts | 27 +++++++++++++++++++ .../src/integrations/browsersession.ts | 16 +++++------ 10 files changed, 38 insertions(+), 35 deletions(-) delete mode 100644 dev-packages/browser-integration-tests/suites/sessions/navigation-mode/test.ts rename dev-packages/browser-integration-tests/suites/sessions/{single-mode => page-lifecycle}/init.js (67%) rename dev-packages/browser-integration-tests/suites/sessions/{single-mode => page-lifecycle}/subject.js (100%) rename dev-packages/browser-integration-tests/suites/sessions/{single-mode => page-lifecycle}/template.html (100%) rename dev-packages/browser-integration-tests/suites/sessions/{single-mode => page-lifecycle}/test.ts (91%) rename dev-packages/browser-integration-tests/suites/sessions/{navigation-mode => route-lifecycle}/init.js (100%) rename dev-packages/browser-integration-tests/suites/sessions/{navigation-mode => route-lifecycle}/subject.js (100%) rename dev-packages/browser-integration-tests/suites/sessions/{navigation-mode => route-lifecycle}/template.html (100%) create mode 100644 dev-packages/browser-integration-tests/suites/sessions/route-lifecycle/test.ts diff --git a/dev-packages/browser-integration-tests/suites/sessions/navigation-mode/test.ts b/dev-packages/browser-integration-tests/suites/sessions/navigation-mode/test.ts deleted file mode 100644 index a9ab937a1816..000000000000 --- a/dev-packages/browser-integration-tests/suites/sessions/navigation-mode/test.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { expect } from '@playwright/test'; -import type { SessionContext } from '@sentry/core'; -import { sentryTest } from '../../../utils/fixtures'; -import { getMultipleSentryEnvelopeRequests } from '../../../utils/helpers'; - -sentryTest('should start new sessions on pushState navigation in default mode.', async ({ getLocalTestUrl, page }) => { - const url = await getLocalTestUrl({ testDir: __dirname }); - - const sessionsPromise = getMultipleSentryEnvelopeRequests(page, 10, { - url, - envelopeType: 'session', - timeout: 4000, - }); - - await page.waitForSelector('#navigate'); - - await page.locator('#navigate').click(); - await page.locator('#navigate').click(); - await page.locator('#navigate').click(); - - const sessions = (await sessionsPromise).filter(session => session.init); - - expect(sessions.length).toBe(3); -}); diff --git a/dev-packages/browser-integration-tests/suites/sessions/single-mode/init.js b/dev-packages/browser-integration-tests/suites/sessions/page-lifecycle/init.js similarity index 67% rename from dev-packages/browser-integration-tests/suites/sessions/single-mode/init.js rename to dev-packages/browser-integration-tests/suites/sessions/page-lifecycle/init.js index 890a54f166eb..6452dbf515f9 100644 --- a/dev-packages/browser-integration-tests/suites/sessions/single-mode/init.js +++ b/dev-packages/browser-integration-tests/suites/sessions/page-lifecycle/init.js @@ -5,5 +5,5 @@ window.Sentry = Sentry; Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', release: '0.1', - integrations: [Sentry.browserSessionIntegration({ mode: 'single' })], + integrations: [Sentry.browserSessionIntegration({ lifecycle: 'page' })], }); diff --git a/dev-packages/browser-integration-tests/suites/sessions/single-mode/subject.js b/dev-packages/browser-integration-tests/suites/sessions/page-lifecycle/subject.js similarity index 100% rename from dev-packages/browser-integration-tests/suites/sessions/single-mode/subject.js rename to dev-packages/browser-integration-tests/suites/sessions/page-lifecycle/subject.js diff --git a/dev-packages/browser-integration-tests/suites/sessions/single-mode/template.html b/dev-packages/browser-integration-tests/suites/sessions/page-lifecycle/template.html similarity index 100% rename from dev-packages/browser-integration-tests/suites/sessions/single-mode/template.html rename to dev-packages/browser-integration-tests/suites/sessions/page-lifecycle/template.html diff --git a/dev-packages/browser-integration-tests/suites/sessions/single-mode/test.ts b/dev-packages/browser-integration-tests/suites/sessions/page-lifecycle/test.ts similarity index 91% rename from dev-packages/browser-integration-tests/suites/sessions/single-mode/test.ts rename to dev-packages/browser-integration-tests/suites/sessions/page-lifecycle/test.ts index bed3fd856f64..1837393f86cc 100644 --- a/dev-packages/browser-integration-tests/suites/sessions/single-mode/test.ts +++ b/dev-packages/browser-integration-tests/suites/sessions/page-lifecycle/test.ts @@ -3,7 +3,7 @@ import type { SessionContext } from '@sentry/core'; import { sentryTest } from '../../../utils/fixtures'; import { getMultipleSentryEnvelopeRequests } from '../../../utils/helpers'; -sentryTest('should start a session on pageload in single mode.', async ({ getLocalTestUrl, page }) => { +sentryTest('should start a session on pageload with page lifecycle.', async ({ getLocalTestUrl, page }) => { const url = await getLocalTestUrl({ testDir: __dirname }); const sessions = await getMultipleSentryEnvelopeRequests(page, 1, { @@ -21,7 +21,7 @@ sentryTest('should start a session on pageload in single mode.', async ({ getLoc }); sentryTest( - 'should NOT start a new session on pushState navigation in single mode.', + 'should NOT start a new session on pushState navigation with page lifecycle.', async ({ getLocalTestUrl, page }) => { const url = await getLocalTestUrl({ testDir: __dirname }); diff --git a/dev-packages/browser-integration-tests/suites/sessions/navigation-mode/init.js b/dev-packages/browser-integration-tests/suites/sessions/route-lifecycle/init.js similarity index 100% rename from dev-packages/browser-integration-tests/suites/sessions/navigation-mode/init.js rename to dev-packages/browser-integration-tests/suites/sessions/route-lifecycle/init.js diff --git a/dev-packages/browser-integration-tests/suites/sessions/navigation-mode/subject.js b/dev-packages/browser-integration-tests/suites/sessions/route-lifecycle/subject.js similarity index 100% rename from dev-packages/browser-integration-tests/suites/sessions/navigation-mode/subject.js rename to dev-packages/browser-integration-tests/suites/sessions/route-lifecycle/subject.js diff --git a/dev-packages/browser-integration-tests/suites/sessions/navigation-mode/template.html b/dev-packages/browser-integration-tests/suites/sessions/route-lifecycle/template.html similarity index 100% rename from dev-packages/browser-integration-tests/suites/sessions/navigation-mode/template.html rename to dev-packages/browser-integration-tests/suites/sessions/route-lifecycle/template.html diff --git a/dev-packages/browser-integration-tests/suites/sessions/route-lifecycle/test.ts b/dev-packages/browser-integration-tests/suites/sessions/route-lifecycle/test.ts new file mode 100644 index 000000000000..4f4f0641feeb --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/sessions/route-lifecycle/test.ts @@ -0,0 +1,27 @@ +import { expect } from '@playwright/test'; +import type { SessionContext } from '@sentry/core'; +import { sentryTest } from '../../../utils/fixtures'; +import { getMultipleSentryEnvelopeRequests } from '../../../utils/helpers'; + +sentryTest( + 'should start new sessions on pushState navigation with route lifecycle (default).', + async ({ getLocalTestUrl, page }) => { + const url = await getLocalTestUrl({ testDir: __dirname }); + + const sessionsPromise = getMultipleSentryEnvelopeRequests(page, 10, { + url, + envelopeType: 'session', + timeout: 4000, + }); + + await page.waitForSelector('#navigate'); + + await page.locator('#navigate').click(); + await page.locator('#navigate').click(); + await page.locator('#navigate').click(); + + const sessions = (await sessionsPromise).filter(session => session.init); + + expect(sessions.length).toBe(3); + }, +); diff --git a/packages/browser/src/integrations/browsersession.ts b/packages/browser/src/integrations/browsersession.ts index a4f0beb651d6..a0eb63034b9f 100644 --- a/packages/browser/src/integrations/browsersession.ts +++ b/packages/browser/src/integrations/browsersession.ts @@ -5,17 +5,17 @@ import { WINDOW } from '../helpers'; interface BrowserSessionOptions { /** - * Controls when sessions are created. + * Controls the session lifecycle - when new sessions are created. * - * - `'single'`: A session is created once when the page is loaded. Session is not + * - `'route'`: A session is created on page load and on every navigation. + * This is the default behavior. + * - `'page'`: A session is created once when the page is loaded. Session is not * updated on navigation. This is useful for webviews or single-page apps where * URL changes should not trigger new sessions. - * - `'navigation'`: A session is created on page load and on every navigation. - * This is the default behavior. * - * @default 'navigation' + * @default 'route' */ - mode?: 'single' | 'navigation'; + lifecycle?: 'route' | 'page'; } /** @@ -25,7 +25,7 @@ interface BrowserSessionOptions { * Note: In order for session tracking to work, you need to set up Releases: https://docs.sentry.io/product/releases/ */ export const browserSessionIntegration = defineIntegration((options: BrowserSessionOptions = {}) => { - const mode = options.mode ?? 'navigation'; + const lifecycle = options.lifecycle ?? 'route'; return { name: 'BrowserSession', @@ -43,7 +43,7 @@ export const browserSessionIntegration = defineIntegration((options: BrowserSess startSession({ ignoreDuration: true }); captureSession(); - if (mode === 'navigation') { + if (lifecycle === 'route') { // We want to create a session for every navigation as well addHistoryInstrumentationHandler(({ from, to }) => { // Don't create an additional session for the initial route or if the location did not change From f7824f4e3f700575f0343876449c4a1624bab27f Mon Sep 17 00:00:00 2001 From: JPeer264 Date: Thu, 5 Feb 2026 10:41:08 +0100 Subject: [PATCH 5/5] chore: update size-limit --- .size-limit.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.size-limit.js b/.size-limit.js index 7f8e1809522f..10abf4062d7d 100644 --- a/.size-limit.js +++ b/.size-limit.js @@ -163,7 +163,7 @@ module.exports = [ path: 'packages/vue/build/esm/index.js', import: createImport('init', 'browserTracingIntegration'), gzip: true, - limit: '44.1 KB', + limit: '45 KB', }, // Svelte SDK (ESM) { @@ -178,7 +178,7 @@ module.exports = [ name: 'CDN Bundle', path: createCDNPath('bundle.min.js'), gzip: true, - limit: '28 KB', + limit: '29 KB', }, { name: 'CDN Bundle (incl. Tracing)',