diff --git a/dev-packages/browser-integration-tests/suites/manual-client/force-init-chrome-extension/init.js b/dev-packages/browser-integration-tests/suites/manual-client/force-init-chrome-extension/init.js new file mode 100644 index 000000000000..5d5cb2799a4e --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/manual-client/force-init-chrome-extension/init.js @@ -0,0 +1,11 @@ +import * as Sentry from '@sentry/browser'; + +window.Sentry = Sentry; + +// We mock this here to simulate a Chrome browser extension +window.chrome = { runtime: { id: 'mock-extension-id' } }; + +Sentry.init({ + dsn: 'https://public@dsn.ingest.sentry.io/1337', + skipBrowserExtensionCheck: true, +}); diff --git a/dev-packages/browser-integration-tests/suites/manual-client/force-init-chrome-extension/test.ts b/dev-packages/browser-integration-tests/suites/manual-client/force-init-chrome-extension/test.ts new file mode 100644 index 000000000000..204544aaa7bc --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/manual-client/force-init-chrome-extension/test.ts @@ -0,0 +1,16 @@ +import { expect } from '@playwright/test'; +import { sentryTest } from '../../../utils/fixtures'; + +sentryTest( + 'initializes inside a Chrome browser extension if `skipBrowserExtensionCheck` is set', + async ({ getLocalTestUrl, page }) => { + const url = await getLocalTestUrl({ testDir: __dirname }); + await page.goto(url); + + const isInitialized = await page.evaluate(() => { + return !!(window as any).Sentry.isInitialized(); + }); + + expect(isInitialized).toBe(true); + }, +); diff --git a/packages/browser/src/client.ts b/packages/browser/src/client.ts index 177d787a438d..851f830d6955 100644 --- a/packages/browser/src/client.ts +++ b/packages/browser/src/client.ts @@ -26,7 +26,26 @@ import { createUserFeedbackEnvelope } from './userfeedback'; */ export type BrowserOptions = Options & BrowserClientReplayOptions & - BrowserClientProfilingOptions; + BrowserClientProfilingOptions & { + /** + * Important: Only set this option if you know what you are doing! + * + * By default, the SDK will check if `Sentry.init` is called in a browser extension. + * In case it is, it will stop initialization and log a warning + * because browser extensions require a different Sentry initialization process: + * https://docs.sentry.io/platforms/javascript/best-practices/shared-environments/ + * + * Setting up the SDK in a browser extension with global error monitoring is not recommended + * and will likely flood you with errors from other web sites or extensions. This can heavily + * impact your quota and cause interference with your and other Sentry SDKs in shared environments. + * + * If this check wrongfully flags your setup as a browser extension, you can set this + * option to `true` to skip the check. + * + * @default false + */ + skipBrowserExtensionCheck?: boolean; + }; /** * Configuration options for the Sentry Browser SDK Client class diff --git a/packages/browser/src/sdk.ts b/packages/browser/src/sdk.ts index 1a0296341341..cd15af8fef1f 100644 --- a/packages/browser/src/sdk.ts +++ b/packages/browser/src/sdk.ts @@ -160,7 +160,7 @@ declare const __SENTRY_RELEASE__: string | undefined; export function init(browserOptions: BrowserOptions = {}): Client | undefined { const options = applyDefaultOptions(browserOptions); - if (shouldShowBrowserExtensionError()) { + if (!options.skipBrowserExtensionCheck && shouldShowBrowserExtensionError()) { consoleSandbox(() => { // eslint-disable-next-line no-console console.error(