diff --git a/.size-limit.js b/.size-limit.js index ca26288b07b3..d66ece2b690d 100644 --- a/.size-limit.js +++ b/.size-limit.js @@ -40,7 +40,7 @@ module.exports = [ path: 'packages/browser/build/npm/esm/index.js', import: createImport('init', 'browserTracingIntegration'), gzip: true, - limit: '38 KB', + limit: '39 KB', }, { name: '@sentry/browser (incl. Tracing, Replay)', diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/multiple-integrations/init.js b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/multiple-integrations/init.js new file mode 100644 index 000000000000..6d4dd43801b8 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/multiple-integrations/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.browserTracingIntegration(), Sentry.browserTracingIntegration()], + tracesSampleRate: 1, +}); diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/multiple-integrations/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/multiple-integrations/test.ts new file mode 100644 index 000000000000..f7f3c50ee052 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/multiple-integrations/test.ts @@ -0,0 +1,22 @@ +import { expect } from '@playwright/test'; + +import { sentryTest } from '../../../../utils/fixtures'; +import { shouldSkipTracingTest } from '../../../../utils/helpers'; + +sentryTest('warns if multiple integrations are used', async ({ getLocalTestUrl, page }) => { + if (shouldSkipTracingTest()) { + sentryTest.skip(); + } + + const msgs: string[] = []; + + page.on('console', msg => { + msgs.push(msg.text()); + }); + + const url = await getLocalTestUrl({ testDir: __dirname }); + + await page.goto(url); + + expect(msgs).toEqual(['Multiple browserTracingIntegration instances are not supported.']); +}); diff --git a/packages/browser/src/tracing/browserTracingIntegration.ts b/packages/browser/src/tracing/browserTracingIntegration.ts index fab45cd1ed4f..5851edfec823 100644 --- a/packages/browser/src/tracing/browserTracingIntegration.ts +++ b/packages/browser/src/tracing/browserTracingIntegration.ts @@ -10,6 +10,7 @@ import { startTrackingWebVitals, } from '@sentry-internal/browser-utils'; import type { Client, IntegrationFn, Span, StartSpanOptions, TransactionSource, WebFetchHeaders } from '@sentry/core'; +import { consoleSandbox } from '@sentry/core'; import { GLOBAL_OBJ, SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON, @@ -217,6 +218,8 @@ const DEFAULT_BROWSER_TRACING_OPTIONS: BrowserTracingOptions = { ...defaultRequestInstrumentationOptions, }; +let _hasBeenInitialized = false; + /** * The Browser Tracing integration automatically instruments browser pageload/navigation * actions as transactions, and captures requests, metrics and errors as spans. @@ -227,6 +230,15 @@ const DEFAULT_BROWSER_TRACING_OPTIONS: BrowserTracingOptions = { * We explicitly export the proper type here, as this has to be extended in some cases. */ export const browserTracingIntegration = ((_options: Partial = {}) => { + if (_hasBeenInitialized) { + consoleSandbox(() => { + // eslint-disable-next-line no-console + console.warn('Multiple browserTracingIntegration instances are not supported.'); + }); + } + + _hasBeenInitialized = true; + /** * This is just a small wrapper that makes `document` optional. * We want to be extra-safe and always check that this exists, to ensure weird environments do not blow up.