Skip to content

feat(react-router): Add component annotation plugin #16472

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 5, 2025
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
14 changes: 13 additions & 1 deletion packages/react-router/src/vite/makeCustomSentryVitePlugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export async function makeCustomSentryVitePlugins(options: SentryReactRouterBuil
org,
project,
telemetry,
reactComponentAnnotation,
release,
} = options;

Expand All @@ -30,6 +31,11 @@ export async function makeCustomSentryVitePlugins(options: SentryReactRouterBuil
},
...unstable_sentryVitePluginOptions?._metaOptions,
},
reactComponentAnnotation: {
enabled: reactComponentAnnotation?.enabled ?? undefined,
ignoredComponents: reactComponentAnnotation?.ignoredComponents ?? undefined,
...unstable_sentryVitePluginOptions?.reactComponentAnnotation,
},
release: {
...unstable_sentryVitePluginOptions?.release,
...release,
Expand All @@ -45,7 +51,13 @@ export async function makeCustomSentryVitePlugins(options: SentryReactRouterBuil
// only use a subset of the plugins as all upload and file deletion tasks will be handled in the buildEnd hook
return [
...sentryVitePlugins.filter(plugin => {
return ['sentry-telemetry-plugin', 'sentry-vite-release-injection-plugin'].includes(plugin.name);
return [
'sentry-telemetry-plugin',
'sentry-vite-release-injection-plugin',
...(reactComponentAnnotation?.enabled || unstable_sentryVitePluginOptions?.reactComponentAnnotation?.enabled
? ['sentry-vite-component-name-annotate-plugin']
: []),
].includes(plugin.name);
}),
];
}
19 changes: 19 additions & 0 deletions packages/react-router/src/vite/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,25 @@ export type SentryReactRouterBuildOptions = {
*/
debug?: boolean;

/**
* Options related to react component name annotations.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* Options related to react component name annotations.
* Options related to react component name annotation.

Copy link
Member Author

Choose a reason for hiding this comment

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

I copied that from the Next.js options. I'm gonna keep it the same and won't change that :)

* Disabled by default, unless a value is set for this option.
* When enabled, your app's DOM will automatically be annotated during build-time with their respective component names.
* This will unlock the capability to search for Replays in Sentry by component name, as well as see component names in breadcrumbs and performance monitoring.
* Please note that this feature is not currently supported by the esbuild bundler plugins, and will only annotate React components
*/
reactComponentAnnotation?: {
/**
* Whether the component name annotate plugin should be enabled or not.
*/
enabled?: boolean;

/**
* A list of strings representing the names of components to ignore. The plugin will not apply `data-sentry` annotations on the DOM element for these components.
*/
ignoredComponents?: string[];
};

/**
* Options for the Sentry Vite plugin to customize the source maps upload process.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ vi.mock('@sentry/vite-plugin', () => ({
.mockReturnValue([
{ name: 'sentry-telemetry-plugin' },
{ name: 'sentry-vite-release-injection-plugin' },
{ name: 'sentry-vite-component-name-annotate-plugin' },
{ name: 'other-plugin' },
]),
}));
Expand Down Expand Up @@ -60,4 +61,24 @@ describe('makeCustomSentryVitePlugins', () => {
expect(plugins?.[0]?.name).toBe('sentry-telemetry-plugin');
expect(plugins?.[1]?.name).toBe('sentry-vite-release-injection-plugin');
});

it('should include component annotation plugin when reactComponentAnnotation.enabled is true', async () => {
const plugins = await makeCustomSentryVitePlugins({ reactComponentAnnotation: { enabled: true } });

expect(plugins).toHaveLength(3);
expect(plugins?.[0]?.name).toBe('sentry-telemetry-plugin');
expect(plugins?.[1]?.name).toBe('sentry-vite-release-injection-plugin');
expect(plugins?.[2]?.name).toBe('sentry-vite-component-name-annotate-plugin');
});

it('should include component annotation plugin when unstable_sentryVitePluginOptions.reactComponentAnnotation.enabled is true', async () => {
const plugins = await makeCustomSentryVitePlugins({
unstable_sentryVitePluginOptions: { reactComponentAnnotation: { enabled: true } },
});

expect(plugins).toHaveLength(3);
expect(plugins?.[0]?.name).toBe('sentry-telemetry-plugin');
expect(plugins?.[1]?.name).toBe('sentry-vite-release-injection-plugin');
expect(plugins?.[2]?.name).toBe('sentry-vite-component-name-annotate-plugin');
});
});
Loading