Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/nextjs/src/config/getBuildPluginOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ export function getBuildPluginOptions({
const skipSourcemapsUpload = shouldSkipSourcemapUpload(buildTool, useRunAfterProductionCompileHook);

return {
applicationKey: sentryBuildOptions.applicationKey,
authToken: sentryBuildOptions.authToken,
headers: sentryBuildOptions.headers,
org: sentryBuildOptions.org,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ export function constructTurbopackConfig({
// so it is safe even for node_modules with strict initialization order.
// We only exclude Next.js build polyfills which contain non-standard syntax that causes
// parse errors when any code is prepended (Turbopack re-parses the loader output).
const applicationKey = userSentryOptions?._experimental?.turbopackApplicationKey;
// eslint-disable-next-line deprecation/deprecation
const applicationKey = userSentryOptions?.applicationKey ?? userSentryOptions?._experimental?.turbopackApplicationKey;
if (applicationKey && nextJsVersion && supportsTurbopackRuleCondition(nextJsVersion)) {
newConfig.rules = safelyAddTurbopackRule(newConfig.rules, {
matcher: '*.{ts,tsx,js,jsx,mjs,cjs}',
Expand Down
16 changes: 15 additions & 1 deletion packages/nextjs/src/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,18 @@ export type SentryBuildOptions = {
};
};

/**
* A key that is used to identify the application in the Sentry bundler plugins.
* This key is used by the `thirdPartyErrorFilterIntegration` to filter out errors
* originating from third-party scripts.
*
* For webpack builds, this is forwarded to the `@sentry/webpack-plugin`.
* For Turbopack builds, this injects module metadata via a custom loader.
*
* @see https://docs.sentry.io/platforms/javascript/configuration/filtering/#using-thirdpartyerrorfilterintegration
*/
applicationKey?: string;

/**
* Options to configure various bundle size optimizations related to the Sentry SDK.
*/
Expand Down Expand Up @@ -738,8 +750,10 @@ export type SentryBuildOptions = {
* webpack builds via its `moduleMetadata` / `applicationKey` option.
*
* Requires Next.js 16+
*
* @deprecated Use the top-level `applicationKey` option instead, which works for both webpack and Turbopack builds.
*/
turbopackApplicationKey?: string;
turbopackApplicationKey?: string; // TODO(v11): remove this option
/**
* Options for React component name annotation in Turbopack builds.
* When enabled, JSX elements are annotated with `data-sentry-component`,
Expand Down
15 changes: 15 additions & 0 deletions packages/nextjs/test/config/getBuildPluginOptions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,21 @@ describe('getBuildPluginOptions', () => {
});
});

it('forwards applicationKey to plugin options', () => {
const sentryBuildOptions: SentryBuildOptions = {
applicationKey: 'my-app-key',
};

const result = getBuildPluginOptions({
sentryBuildOptions,
releaseName: mockReleaseName,
distDirAbsPath: mockDistDirAbsPath,
buildTool: 'after-production-compile-webpack',
});

expect(result.applicationKey).toBe('my-app-key');
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feat PR missing integration or E2E test

Low Severity

This is a feat PR that adds a new top-level applicationKey option, but it only includes unit tests. Per the project review rules, feat PRs are expected to include at least one integration or E2E test. Consider adding an E2E test that verifies the applicationKey option works end-to-end for either webpack or turbopack builds, similar to the existing browser-webworker-vite E2E test that exercises applicationKey.

Additional Locations (1)
Fix in Cursor Fix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

Reviewed by Cursor Bugbot for commit 79d9231. Configure here.


it('normalizes Windows paths to posix for glob patterns in after-production-compile builds', () => {
const windowsPath = 'C:\\Users\\test\\.next';
const sentryBuildOptions: SentryBuildOptions = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -977,6 +977,39 @@ describe('moduleMetadataInjection with applicationKey', () => {
});
});

it('should add metadata loader rule when top-level applicationKey is set and Next.js >= 16', () => {
const userNextConfig: NextConfigObject = {};

const result = constructTurbopackConfig({
userNextConfig,
userSentryOptions: { applicationKey: 'my-top-level-key' },
nextJsVersion: '16.0.0',
});

const rule = result.rules!['*.{ts,tsx,js,jsx,mjs,cjs}'] as {
loaders: Array<{ loader: string; options: { applicationKey: string } }>;
};
expect(rule.loaders[0]!.options.applicationKey).toBe('my-top-level-key');
});

it('should prefer top-level applicationKey over deprecated _experimental.turbopackApplicationKey', () => {
const userNextConfig: NextConfigObject = {};

const result = constructTurbopackConfig({
userNextConfig,
userSentryOptions: {
applicationKey: 'top-level-key',
_experimental: { turbopackApplicationKey: 'deprecated-key' },
},
nextJsVersion: '16.0.0',
});

const rule = result.rules!['*.{ts,tsx,js,jsx,mjs,cjs}'] as {
loaders: Array<{ loader: string; options: { applicationKey: string } }>;
};
expect(rule.loaders[0]!.options.applicationKey).toBe('top-level-key');
});

it('should only exclude Next.js polyfills, not all foreign modules', () => {
const userNextConfig: NextConfigObject = {};

Expand Down
Loading