From 534eeb7ca2882f1aedf1bc51c95a39f62b5ebbde Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Mon, 1 Dec 2025 16:58:26 +0100 Subject: [PATCH 1/7] feat: added webpack treeshaking flags --- packages/nextjs/src/config/types.ts | 30 ++++++++++++++++++ packages/nextjs/src/config/webpack.ts | 45 ++++++++++++++++++++++----- 2 files changed, 68 insertions(+), 7 deletions(-) diff --git a/packages/nextjs/src/config/types.ts b/packages/nextjs/src/config/types.ts index c7472c08fc20..29a16d08423d 100644 --- a/packages/nextjs/src/config/types.ts +++ b/packages/nextjs/src/config/types.ts @@ -112,6 +112,36 @@ export type SentryBuildWebpackOptions = { * Removes Sentry SDK logger statements from the bundle. Note that this doesn't affect Sentry Logs. */ removeDebugLogging?: boolean; + + /** + * Setting this to true will tree-shake any SDK code that is related to tracing and performance monitoring. + */ + tracing?: boolean; + + /** + * Replacing this flag with true will tree shake any SDK code related to capturing iframe content with Session Replay. + * It's only relevant when using Session Replay. Enable this flag if you don't want to record any iframes. + * This has no effect if you did not add `replayIntegration`. + */ + excludeReplayIframe?: boolean; + + /** + * Replacing this flag with true will tree shake any SDK code related to capturing shadow dom elements with Session Replay. + * It's only relevant when using Session Replay. + * Enable this flag if you don't want to record any shadow dom elements. + * This has no effect if you did not add `replayIntegration`. + */ + excludeReplayShadowDOM?: boolean; + + /** + * Replacing this flag with true will tree shake any SDK code that's related to the included compression web worker for Session Replay. + * It's only relevant when using Session Replay. + * Enable this flag if you want to host a compression worker yourself. + * See Using a Custom Compression Worker for details. + * We don't recommend enabling this flag unless you provide a custom worker URL. + * This has no effect if you did not add `replayIntegration`. + */ + excludeReplayCompressionWorker?: boolean; }; /** diff --git a/packages/nextjs/src/config/webpack.ts b/packages/nextjs/src/config/webpack.ts index 3630e1005c87..7450dcf7a773 100644 --- a/packages/nextjs/src/config/webpack.ts +++ b/packages/nextjs/src/config/webpack.ts @@ -428,13 +428,8 @@ export function constructWebpackConfigFunction({ } } - if (userSentryOptions.webpack?.treeshake?.removeDebugLogging) { - newConfig.plugins = newConfig.plugins || []; - newConfig.plugins.push( - new buildContext.webpack.DefinePlugin({ - __SENTRY_DEBUG__: false, - }), - ); + if (userSentryOptions.webpack?.treeshake) { + setupTreeshakingFromConfig(userSentryOptions, newConfig, buildContext); } // We inject a map of dependencies that the nextjs app has, as we cannot reliably extract them at runtime, sadly @@ -912,3 +907,39 @@ function _getModules(projectDir: string): Record { return {}; } } + +/** + * Sets up the tree-shaking flags based on the user's configuration. + * https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/tree-shaking/ + */ +function setupTreeshakingFromConfig( + userSentryOptions: SentryBuildOptions, + newConfig: WebpackConfigObjectWithModuleRules, + buildContext: BuildContext, +): void { + const defines: Record = {}; + + newConfig.plugins = newConfig.plugins || []; + + if (userSentryOptions.webpack?.treeshake?.removeDebugLogging) { + defines.__SENTRY_DEBUG__ = false; + } + + if (userSentryOptions.webpack?.treeshake?.tracing) { + defines.__SENTRY_TRACING__ = false; + } + + if (userSentryOptions.webpack?.treeshake?.excludeReplayIframe) { + defines.__RRWEB_EXCLUDE_IFRAME__ = true; + } + + if (userSentryOptions.webpack?.treeshake?.excludeReplayShadowDOM) { + defines.__RRWEB_EXCLUDE_SHADOW_DOM__ = true; + } + + if (userSentryOptions.webpack?.treeshake?.excludeReplayCompressionWorker) { + defines.__SENTRY_EXCLUDE_REPLAY_WORKER__ = true; + } + + newConfig.plugins.push(new buildContext.webpack.DefinePlugin(defines)); +} From bf868fb250fcac5657f7b0895219aeb1b246795d Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Mon, 1 Dec 2025 16:58:39 +0100 Subject: [PATCH 2/7] tests: added tests --- packages/nextjs/test/config/fixtures.ts | 4 +- .../webpack/constructWebpackConfig.test.ts | 406 ++++++++++++++++++ 2 files changed, 409 insertions(+), 1 deletion(-) diff --git a/packages/nextjs/test/config/fixtures.ts b/packages/nextjs/test/config/fixtures.ts index 5f5d4a2d3504..f8592148161c 100644 --- a/packages/nextjs/test/config/fixtures.ts +++ b/packages/nextjs/test/config/fixtures.ts @@ -101,7 +101,9 @@ export function getBuildContext( } as NextConfigObject, webpack: { version: webpackVersion, - DefinePlugin: class {} as any, + DefinePlugin: class { + constructor(public definitions: Record) {} + } as any, ProvidePlugin: class { constructor(public definitions: Record) {} } as any, diff --git a/packages/nextjs/test/config/webpack/constructWebpackConfig.test.ts b/packages/nextjs/test/config/webpack/constructWebpackConfig.test.ts index b8cfb4015512..157f64060ad4 100644 --- a/packages/nextjs/test/config/webpack/constructWebpackConfig.test.ts +++ b/packages/nextjs/test/config/webpack/constructWebpackConfig.test.ts @@ -383,4 +383,410 @@ describe('constructWebpackConfigFunction()', () => { vi.restoreAllMocks(); }); }); + + describe('treeshaking flags', () => { + it('does not add DefinePlugin when treeshake option is not set', async () => { + vi.spyOn(core, 'loadModule').mockImplementation(() => ({ + sentryWebpackPlugin: () => ({ + _name: 'sentry-webpack-plugin', + }), + })); + + const finalWebpackConfig = await materializeFinalWebpackConfig({ + exportedNextConfig, + incomingWebpackConfig: serverWebpackConfig, + incomingWebpackBuildContext: serverBuildContext, + sentryBuildTimeOptions: {}, + }); + + const definePlugin = finalWebpackConfig.plugins?.find( + plugin => plugin.constructor.name === 'DefinePlugin', + ) as any; + + // Should not have a DefinePlugin for treeshaking (may have one for __SENTRY_SERVER_MODULES__) + if (definePlugin) { + expect(definePlugin.definitions).not.toHaveProperty('__SENTRY_DEBUG__'); + expect(definePlugin.definitions).not.toHaveProperty('__SENTRY_TRACING__'); + expect(definePlugin.definitions).not.toHaveProperty('__RRWEB_EXCLUDE_IFRAME__'); + expect(definePlugin.definitions).not.toHaveProperty('__RRWEB_EXCLUDE_SHADOW_DOM__'); + expect(definePlugin.definitions).not.toHaveProperty('__SENTRY_EXCLUDE_REPLAY_WORKER__'); + } + }); + + it('does not add DefinePlugin when treeshake option is empty object', async () => { + vi.spyOn(core, 'loadModule').mockImplementation(() => ({ + sentryWebpackPlugin: () => ({ + _name: 'sentry-webpack-plugin', + }), + })); + + const finalWebpackConfig = await materializeFinalWebpackConfig({ + exportedNextConfig, + incomingWebpackConfig: serverWebpackConfig, + incomingWebpackBuildContext: serverBuildContext, + sentryBuildTimeOptions: { + webpack: { + treeshake: {}, + }, + }, + }); + + const definePlugin = finalWebpackConfig.plugins?.find( + plugin => plugin.constructor.name === 'DefinePlugin', + ) as any; + + // Should not have treeshaking flags in DefinePlugin + if (definePlugin) { + expect(definePlugin.definitions).not.toHaveProperty('__SENTRY_DEBUG__'); + expect(definePlugin.definitions).not.toHaveProperty('__SENTRY_TRACING__'); + expect(definePlugin.definitions).not.toHaveProperty('__RRWEB_EXCLUDE_IFRAME__'); + expect(definePlugin.definitions).not.toHaveProperty('__RRWEB_EXCLUDE_SHADOW_DOM__'); + expect(definePlugin.definitions).not.toHaveProperty('__SENTRY_EXCLUDE_REPLAY_WORKER__'); + } + }); + + it('adds __SENTRY_DEBUG__ flag when debugLogging is true', async () => { + vi.spyOn(core, 'loadModule').mockImplementation(() => ({ + sentryWebpackPlugin: () => ({ + _name: 'sentry-webpack-plugin', + }), + })); + + const finalWebpackConfig = await materializeFinalWebpackConfig({ + exportedNextConfig, + incomingWebpackConfig: serverWebpackConfig, + incomingWebpackBuildContext: serverBuildContext, + sentryBuildTimeOptions: { + webpack: { + treeshake: { + debugLogging: true, + }, + }, + }, + }); + + const definePlugin = finalWebpackConfig.plugins?.find( + plugin => plugin.constructor.name === 'DefinePlugin' && plugin.definitions?.__SENTRY_DEBUG__ !== undefined, + ) as any; + + expect(definePlugin).toBeDefined(); + expect(definePlugin.definitions.__SENTRY_DEBUG__).toBe(false); + }); + + it('adds __SENTRY_TRACING__ flag when tracing is true', async () => { + vi.spyOn(core, 'loadModule').mockImplementation(() => ({ + sentryWebpackPlugin: () => ({ + _name: 'sentry-webpack-plugin', + }), + })); + + const finalWebpackConfig = await materializeFinalWebpackConfig({ + exportedNextConfig, + incomingWebpackConfig: serverWebpackConfig, + incomingWebpackBuildContext: serverBuildContext, + sentryBuildTimeOptions: { + webpack: { + treeshake: { + tracing: true, + }, + }, + }, + }); + + const definePlugin = finalWebpackConfig.plugins?.find( + plugin => plugin.constructor.name === 'DefinePlugin' && plugin.definitions?.__SENTRY_TRACING__ !== undefined, + ) as any; + + expect(definePlugin).toBeDefined(); + expect(definePlugin.definitions.__SENTRY_TRACING__).toBe(false); + }); + + it('adds __RRWEB_EXCLUDE_IFRAME__ flag when excludeReplayIframe is true', async () => { + vi.spyOn(core, 'loadModule').mockImplementation(() => ({ + sentryWebpackPlugin: () => ({ + _name: 'sentry-webpack-plugin', + }), + })); + + const finalWebpackConfig = await materializeFinalWebpackConfig({ + exportedNextConfig, + incomingWebpackConfig: serverWebpackConfig, + incomingWebpackBuildContext: serverBuildContext, + sentryBuildTimeOptions: { + webpack: { + treeshake: { + excludeReplayIframe: true, + }, + }, + }, + }); + + const definePlugin = finalWebpackConfig.plugins?.find( + plugin => + plugin.constructor.name === 'DefinePlugin' && plugin.definitions?.__RRWEB_EXCLUDE_IFRAME__ !== undefined, + ) as any; + + expect(definePlugin).toBeDefined(); + expect(definePlugin.definitions.__RRWEB_EXCLUDE_IFRAME__).toBe(true); + }); + + it('adds __RRWEB_EXCLUDE_SHADOW_DOM__ flag when excludeReplayShadowDOM is true', async () => { + vi.spyOn(core, 'loadModule').mockImplementation(() => ({ + sentryWebpackPlugin: () => ({ + _name: 'sentry-webpack-plugin', + }), + })); + + const finalWebpackConfig = await materializeFinalWebpackConfig({ + exportedNextConfig, + incomingWebpackConfig: serverWebpackConfig, + incomingWebpackBuildContext: serverBuildContext, + sentryBuildTimeOptions: { + webpack: { + treeshake: { + excludeReplayShadowDOM: true, + }, + }, + }, + }); + + const definePlugin = finalWebpackConfig.plugins?.find( + plugin => + plugin.constructor.name === 'DefinePlugin' && plugin.definitions?.__RRWEB_EXCLUDE_SHADOW_DOM__ !== undefined, + ) as any; + + expect(definePlugin).toBeDefined(); + expect(definePlugin.definitions.__RRWEB_EXCLUDE_SHADOW_DOM__).toBe(true); + }); + + it('adds __SENTRY_EXCLUDE_REPLAY_WORKER__ flag when excludeReplayCompressionWorker is true', async () => { + vi.spyOn(core, 'loadModule').mockImplementation(() => ({ + sentryWebpackPlugin: () => ({ + _name: 'sentry-webpack-plugin', + }), + })); + + const finalWebpackConfig = await materializeFinalWebpackConfig({ + exportedNextConfig, + incomingWebpackConfig: serverWebpackConfig, + incomingWebpackBuildContext: serverBuildContext, + sentryBuildTimeOptions: { + webpack: { + treeshake: { + excludeReplayCompressionWorker: true, + }, + }, + }, + }); + + const definePlugin = finalWebpackConfig.plugins?.find( + plugin => + plugin.constructor.name === 'DefinePlugin' && + plugin.definitions?.__SENTRY_EXCLUDE_REPLAY_WORKER__ !== undefined, + ) as any; + + expect(definePlugin).toBeDefined(); + expect(definePlugin.definitions.__SENTRY_EXCLUDE_REPLAY_WORKER__).toBe(true); + }); + + it('adds all flags when all treeshake options are enabled', async () => { + vi.spyOn(core, 'loadModule').mockImplementation(() => ({ + sentryWebpackPlugin: () => ({ + _name: 'sentry-webpack-plugin', + }), + })); + + const finalWebpackConfig = await materializeFinalWebpackConfig({ + exportedNextConfig, + incomingWebpackConfig: serverWebpackConfig, + incomingWebpackBuildContext: serverBuildContext, + sentryBuildTimeOptions: { + webpack: { + treeshake: { + debugLogging: true, + tracing: true, + excludeReplayIframe: true, + excludeReplayShadowDOM: true, + excludeReplayCompressionWorker: true, + }, + }, + }, + }); + + const definePlugins = finalWebpackConfig.plugins?.filter( + plugin => plugin.constructor.name === 'DefinePlugin', + ) as any[]; + + // Find the plugin that has treeshaking flags (there may be another for __SENTRY_SERVER_MODULES__) + const treeshakePlugin = definePlugins.find( + plugin => + plugin.definitions.__SENTRY_DEBUG__ !== undefined || + plugin.definitions.__SENTRY_TRACING__ !== undefined || + plugin.definitions.__RRWEB_EXCLUDE_IFRAME__ !== undefined || + plugin.definitions.__RRWEB_EXCLUDE_SHADOW_DOM__ !== undefined || + plugin.definitions.__SENTRY_EXCLUDE_REPLAY_WORKER__ !== undefined, + ); + + expect(treeshakePlugin).toBeDefined(); + expect(treeshakePlugin.definitions.__SENTRY_DEBUG__).toBe(false); + expect(treeshakePlugin.definitions.__SENTRY_TRACING__).toBe(false); + expect(treeshakePlugin.definitions.__RRWEB_EXCLUDE_IFRAME__).toBe(true); + expect(treeshakePlugin.definitions.__RRWEB_EXCLUDE_SHADOW_DOM__).toBe(true); + expect(treeshakePlugin.definitions.__SENTRY_EXCLUDE_REPLAY_WORKER__).toBe(true); + }); + + it('does not add flags when treeshake options are false', async () => { + vi.spyOn(core, 'loadModule').mockImplementation(() => ({ + sentryWebpackPlugin: () => ({ + _name: 'sentry-webpack-plugin', + }), + })); + + const finalWebpackConfig = await materializeFinalWebpackConfig({ + exportedNextConfig, + incomingWebpackConfig: serverWebpackConfig, + incomingWebpackBuildContext: serverBuildContext, + sentryBuildTimeOptions: { + webpack: { + treeshake: { + debugLogging: false, + tracing: false, + excludeReplayIframe: false, + excludeReplayShadowDOM: false, + excludeReplayCompressionWorker: false, + }, + }, + }, + }); + + const definePlugin = finalWebpackConfig.plugins?.find( + plugin => plugin.constructor.name === 'DefinePlugin', + ) as any; + + // Should not have treeshaking flags + if (definePlugin) { + expect(definePlugin.definitions).not.toHaveProperty('__SENTRY_DEBUG__'); + expect(definePlugin.definitions).not.toHaveProperty('__SENTRY_TRACING__'); + expect(definePlugin.definitions).not.toHaveProperty('__RRWEB_EXCLUDE_IFRAME__'); + expect(definePlugin.definitions).not.toHaveProperty('__RRWEB_EXCLUDE_SHADOW_DOM__'); + expect(definePlugin.definitions).not.toHaveProperty('__SENTRY_EXCLUDE_REPLAY_WORKER__'); + } + }); + + it('works for client builds', async () => { + vi.spyOn(core, 'loadModule').mockImplementation(() => ({ + sentryWebpackPlugin: () => ({ + _name: 'sentry-webpack-plugin', + }), + })); + + const finalWebpackConfig = await materializeFinalWebpackConfig({ + exportedNextConfig, + incomingWebpackConfig: clientWebpackConfig, + incomingWebpackBuildContext: clientBuildContext, + sentryBuildTimeOptions: { + webpack: { + treeshake: { + debugLogging: true, + tracing: true, + }, + }, + }, + }); + + const definePlugins = finalWebpackConfig.plugins?.filter( + plugin => plugin.constructor.name === 'DefinePlugin', + ) as any[]; + + const treeshakePlugin = definePlugins.find( + plugin => + plugin.definitions.__SENTRY_DEBUG__ !== undefined || plugin.definitions.__SENTRY_TRACING__ !== undefined, + ); + + expect(treeshakePlugin).toBeDefined(); + expect(treeshakePlugin.definitions.__SENTRY_DEBUG__).toBe(false); + expect(treeshakePlugin.definitions.__SENTRY_TRACING__).toBe(false); + }); + + it('works for edge builds', async () => { + vi.spyOn(core, 'loadModule').mockImplementation(() => ({ + sentryWebpackPlugin: () => ({ + _name: 'sentry-webpack-plugin', + }), + })); + + const finalWebpackConfig = await materializeFinalWebpackConfig({ + exportedNextConfig, + incomingWebpackConfig: serverWebpackConfig, + incomingWebpackBuildContext: edgeBuildContext, + sentryBuildTimeOptions: { + webpack: { + treeshake: { + excludeReplayIframe: true, + excludeReplayShadowDOM: true, + }, + }, + }, + }); + + const definePlugins = finalWebpackConfig.plugins?.filter( + plugin => plugin.constructor.name === 'DefinePlugin', + ) as any[]; + + const treeshakePlugin = definePlugins.find( + plugin => + plugin.definitions.__RRWEB_EXCLUDE_IFRAME__ !== undefined || + plugin.definitions.__RRWEB_EXCLUDE_SHADOW_DOM__ !== undefined, + ); + + expect(treeshakePlugin).toBeDefined(); + expect(treeshakePlugin.definitions.__RRWEB_EXCLUDE_IFRAME__).toBe(true); + expect(treeshakePlugin.definitions.__RRWEB_EXCLUDE_SHADOW_DOM__).toBe(true); + }); + + it('only adds flags for enabled options', async () => { + vi.spyOn(core, 'loadModule').mockImplementation(() => ({ + sentryWebpackPlugin: () => ({ + _name: 'sentry-webpack-plugin', + }), + })); + + const finalWebpackConfig = await materializeFinalWebpackConfig({ + exportedNextConfig, + incomingWebpackConfig: serverWebpackConfig, + incomingWebpackBuildContext: serverBuildContext, + sentryBuildTimeOptions: { + webpack: { + treeshake: { + debugLogging: true, + tracing: false, // disabled + excludeReplayIframe: true, + excludeReplayShadowDOM: false, // disabled + excludeReplayCompressionWorker: true, + }, + }, + }, + }); + + const definePlugins = finalWebpackConfig.plugins?.filter( + plugin => plugin.constructor.name === 'DefinePlugin', + ) as any[]; + + const treeshakePlugin = definePlugins.find( + plugin => + plugin.definitions.__SENTRY_DEBUG__ !== undefined || + plugin.definitions.__RRWEB_EXCLUDE_IFRAME__ !== undefined || + plugin.definitions.__SENTRY_EXCLUDE_REPLAY_WORKER__ !== undefined, + ); + + expect(treeshakePlugin).toBeDefined(); + // Should have enabled flags + expect(treeshakePlugin.definitions.__SENTRY_DEBUG__).toBe(false); + expect(treeshakePlugin.definitions.__RRWEB_EXCLUDE_IFRAME__).toBe(true); + expect(treeshakePlugin.definitions.__SENTRY_EXCLUDE_REPLAY_WORKER__).toBe(true); + // Should not have disabled flags + expect(treeshakePlugin.definitions).not.toHaveProperty('__SENTRY_TRACING__'); + expect(treeshakePlugin.definitions).not.toHaveProperty('__RRWEB_EXCLUDE_SHADOW_DOM__'); + }); + }); }); From 547fccf2f6608f97849457e07217fdf97f5f661c Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Tue, 2 Dec 2025 09:34:12 +0100 Subject: [PATCH 3/7] fix: avoid adding defne plugins if no treeshake opts specified --- packages/nextjs/src/config/webpack.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/nextjs/src/config/webpack.ts b/packages/nextjs/src/config/webpack.ts index 7450dcf7a773..5537f13ca683 100644 --- a/packages/nextjs/src/config/webpack.ts +++ b/packages/nextjs/src/config/webpack.ts @@ -941,5 +941,8 @@ function setupTreeshakingFromConfig( defines.__SENTRY_EXCLUDE_REPLAY_WORKER__ = true; } - newConfig.plugins.push(new buildContext.webpack.DefinePlugin(defines)); + // Only add DefinePlugin if there are actual defines to set + if (Object.keys(defines).length > 0) { + newConfig.plugins.push(new buildContext.webpack.DefinePlugin(defines)); + } } From d95ec0748a8313d8d4a4940fe3393ed43c8e9cd6 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Fri, 5 Dec 2025 10:24:16 +0100 Subject: [PATCH 4/7] chore: comment casing Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- packages/nextjs/src/config/types.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/nextjs/src/config/types.ts b/packages/nextjs/src/config/types.ts index 29a16d08423d..9fe59ac23575 100644 --- a/packages/nextjs/src/config/types.ts +++ b/packages/nextjs/src/config/types.ts @@ -126,9 +126,9 @@ export type SentryBuildWebpackOptions = { excludeReplayIframe?: boolean; /** - * Replacing this flag with true will tree shake any SDK code related to capturing shadow dom elements with Session Replay. + * Replacing this flag with true will tree shake any SDK code related to capturing shadow DOM elements with Session Replay. * It's only relevant when using Session Replay. - * Enable this flag if you don't want to record any shadow dom elements. + * Enable this flag if you don't want to record any shadow DOM elements. * This has no effect if you did not add `replayIntegration`. */ excludeReplayShadowDOM?: boolean; From ab62e3e1f8af1e8d640011571df6c24934442f83 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Fri, 5 Dec 2025 10:30:02 +0100 Subject: [PATCH 5/7] docs: improved comments writing style --- packages/nextjs/src/config/types.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/nextjs/src/config/types.ts b/packages/nextjs/src/config/types.ts index 9fe59ac23575..1db3f7077a19 100644 --- a/packages/nextjs/src/config/types.ts +++ b/packages/nextjs/src/config/types.ts @@ -114,19 +114,19 @@ export type SentryBuildWebpackOptions = { removeDebugLogging?: boolean; /** - * Setting this to true will tree-shake any SDK code that is related to tracing and performance monitoring. + * Setting this to true will treeshake any SDK code that is related to tracing and performance monitoring. */ tracing?: boolean; /** - * Replacing this flag with true will tree shake any SDK code related to capturing iframe content with Session Replay. + * Setting this flag to `true` will tree shake any SDK code related to capturing iframe content with Session Replay. * It's only relevant when using Session Replay. Enable this flag if you don't want to record any iframes. * This has no effect if you did not add `replayIntegration`. */ excludeReplayIframe?: boolean; /** - * Replacing this flag with true will tree shake any SDK code related to capturing shadow DOM elements with Session Replay. + * Setting this flag to `true` will tree shake any SDK code related to capturing shadow dom elements with Session Replay. * It's only relevant when using Session Replay. * Enable this flag if you don't want to record any shadow DOM elements. * This has no effect if you did not add `replayIntegration`. @@ -134,7 +134,7 @@ export type SentryBuildWebpackOptions = { excludeReplayShadowDOM?: boolean; /** - * Replacing this flag with true will tree shake any SDK code that's related to the included compression web worker for Session Replay. + * Setting this flag to `true` will tree shake any SDK code that is related to the included compression web worker for Session Replay. * It's only relevant when using Session Replay. * Enable this flag if you want to host a compression worker yourself. * See Using a Custom Compression Worker for details. @@ -433,7 +433,7 @@ export type SentryBuildOptions = { */ bundleSizeOptimizations?: { /** - * If set to `true`, the Sentry SDK will attempt to tree-shake (remove) any debugging code within itself during the build. + * If set to `true`, the Sentry SDK will attempt to treeshake (remove) any debugging code within itself during the build. * Note that the success of this depends on tree shaking being enabled in your build tooling. * * Setting this option to `true` will disable features like the SDK's `debug` option. @@ -441,14 +441,14 @@ export type SentryBuildOptions = { excludeDebugStatements?: boolean; /** - * If set to `true`, the Sentry SDK will attempt to tree-shake (remove) code within itself that is related to tracing and performance monitoring. + * If set to `true`, the Sentry SDK will attempt to treeshake (remove) code within itself that is related to tracing and performance monitoring. * Note that the success of this depends on tree shaking being enabled in your build tooling. * **Notice:** Do not enable this when you're using any performance monitoring-related SDK features (e.g. `Sentry.startTransaction()`). */ excludeTracing?: boolean; /** - * If set to `true`, the Sentry SDK will attempt to tree-shake (remove) code related to the SDK's Session Replay Shadow DOM recording functionality. + * If set to `true`, the Sentry SDK will attempt to treeshake (remove) code related to the SDK's Session Replay Shadow DOM recording functionality. * Note that the success of this depends on tree shaking being enabled in your build tooling. * * This option is safe to be used when you do not want to capture any Shadow DOM activity via Sentry Session Replay. @@ -456,7 +456,7 @@ export type SentryBuildOptions = { excludeReplayShadowDom?: boolean; /** - * If set to `true`, the Sentry SDK will attempt to tree-shake (remove) code related to the SDK's Session Replay `iframe` recording functionality. + * If set to `true`, the Sentry SDK will attempt to treeshake (remove) code related to the SDK's Session Replay `iframe` recording functionality. * Note that the success of this depends on tree shaking being enabled in your build tooling. * * You can safely do this when you do not want to capture any `iframe` activity via Sentry Session Replay. @@ -464,7 +464,7 @@ export type SentryBuildOptions = { excludeReplayIframe?: boolean; /** - * If set to `true`, the Sentry SDK will attempt to tree-shake (remove) code related to the SDK's Session Replay's Compression Web Worker. + * If set to `true`, the Sentry SDK will attempt to treeshake (remove) code related to the SDK's Session Replay's Compression Web Worker. * Note that the success of this depends on tree shaking being enabled in your build tooling. * * **Notice:** You should only use this option if you manually host a compression worker and configure it in your Sentry Session Replay integration config via the `workerUrl` option. From c8832af91d29c6d97b88630ffc7f8d1816d11f70 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Fri, 5 Dec 2025 10:55:11 +0100 Subject: [PATCH 6/7] ref: rename tracing treeshake option for clarity --- packages/nextjs/src/config/types.ts | 2 +- packages/nextjs/src/config/webpack.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/nextjs/src/config/types.ts b/packages/nextjs/src/config/types.ts index 1db3f7077a19..325e3f1d3187 100644 --- a/packages/nextjs/src/config/types.ts +++ b/packages/nextjs/src/config/types.ts @@ -116,7 +116,7 @@ export type SentryBuildWebpackOptions = { /** * Setting this to true will treeshake any SDK code that is related to tracing and performance monitoring. */ - tracing?: boolean; + removeTracing?: boolean; /** * Setting this flag to `true` will tree shake any SDK code related to capturing iframe content with Session Replay. diff --git a/packages/nextjs/src/config/webpack.ts b/packages/nextjs/src/config/webpack.ts index 5537f13ca683..60f227b3c42c 100644 --- a/packages/nextjs/src/config/webpack.ts +++ b/packages/nextjs/src/config/webpack.ts @@ -925,7 +925,7 @@ function setupTreeshakingFromConfig( defines.__SENTRY_DEBUG__ = false; } - if (userSentryOptions.webpack?.treeshake?.tracing) { + if (userSentryOptions.webpack?.treeshake?.removeTracing) { defines.__SENTRY_TRACING__ = false; } From de51fb2ab489321ebd7d00733d6a1f69576a1eb2 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Fri, 5 Dec 2025 16:26:27 +0100 Subject: [PATCH 7/7] test: update test config names --- .../webpack/constructWebpackConfig.test.ts | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/nextjs/test/config/webpack/constructWebpackConfig.test.ts b/packages/nextjs/test/config/webpack/constructWebpackConfig.test.ts index 157f64060ad4..debc0ed77ae4 100644 --- a/packages/nextjs/test/config/webpack/constructWebpackConfig.test.ts +++ b/packages/nextjs/test/config/webpack/constructWebpackConfig.test.ts @@ -459,7 +459,7 @@ describe('constructWebpackConfigFunction()', () => { sentryBuildTimeOptions: { webpack: { treeshake: { - debugLogging: true, + removeDebugLogging: true, }, }, }, @@ -487,7 +487,7 @@ describe('constructWebpackConfigFunction()', () => { sentryBuildTimeOptions: { webpack: { treeshake: { - tracing: true, + removeTracing: true, }, }, }, @@ -603,8 +603,8 @@ describe('constructWebpackConfigFunction()', () => { sentryBuildTimeOptions: { webpack: { treeshake: { - debugLogging: true, - tracing: true, + removeDebugLogging: true, + removeTracing: true, excludeReplayIframe: true, excludeReplayShadowDOM: true, excludeReplayCompressionWorker: true, @@ -649,8 +649,8 @@ describe('constructWebpackConfigFunction()', () => { sentryBuildTimeOptions: { webpack: { treeshake: { - debugLogging: false, - tracing: false, + removeDebugLogging: false, + removeTracing: false, excludeReplayIframe: false, excludeReplayShadowDOM: false, excludeReplayCompressionWorker: false, @@ -687,8 +687,8 @@ describe('constructWebpackConfigFunction()', () => { sentryBuildTimeOptions: { webpack: { treeshake: { - debugLogging: true, - tracing: true, + removeDebugLogging: true, + removeTracing: true, }, }, }, @@ -758,8 +758,8 @@ describe('constructWebpackConfigFunction()', () => { sentryBuildTimeOptions: { webpack: { treeshake: { - debugLogging: true, - tracing: false, // disabled + removeDebugLogging: true, + removeTracing: false, // disabled excludeReplayIframe: true, excludeReplayShadowDOM: false, // disabled excludeReplayCompressionWorker: true,