diff --git a/dev-packages/e2e-tests/test-applications/tanstackstart-react/src/router.tsx b/dev-packages/e2e-tests/test-applications/tanstackstart-react/src/router.tsx index b1c6f7727a26..bdef82d3d5e2 100644 --- a/dev-packages/e2e-tests/test-applications/tanstackstart-react/src/router.tsx +++ b/dev-packages/e2e-tests/test-applications/tanstackstart-react/src/router.tsx @@ -12,10 +12,10 @@ export const getRouter = () => { Sentry.init({ environment: 'qa', // dynamic sampling bias to keep transactions dsn: 'https://public@dsn.ingest.sentry.io/1337', - integrations: [Sentry.tanstackRouterBrowserTracingIntegration(router)], // We recommend adjusting this value in production, or using tracesSampler // for finer control tracesSampleRate: 1.0, + router: router, release: 'e2e-test', tunnel: 'http://localhost:3031/', // proxy server }); diff --git a/dev-packages/e2e-tests/test-applications/tanstackstart-react/tests/routing-instrumentation.test.ts b/dev-packages/e2e-tests/test-applications/tanstackstart-react/tests/routing-instrumentation.test.ts new file mode 100644 index 000000000000..8b0b0200e7bc --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/tanstackstart-react/tests/routing-instrumentation.test.ts @@ -0,0 +1,32 @@ +import { expect, test } from '@playwright/test'; +import { waitForTransaction } from '@sentry-internal/test-utils'; + +// we have more thorough tests for tanstack-router in a separate e2e test +// so here we just do a basic check to verify that the integration is automatically enabled if tracing is enabled +test('sends a pageload transaction', async ({ page }) => { + const transactionPromise = waitForTransaction('tanstackstart-react', async transactionEvent => { + return !!transactionEvent?.transaction && transactionEvent.contexts?.trace?.op === 'pageload'; + }); + + await page.goto(`/`); + + const rootSpan = await transactionPromise; + + expect(rootSpan).toMatchObject({ + contexts: { + trace: { + data: { + 'sentry.source': 'route', + 'sentry.origin': 'auto.pageload.react.tanstack_router', + 'sentry.op': 'pageload', + }, + op: 'pageload', + origin: 'auto.pageload.react.tanstack_router', + }, + }, + transaction: '/', + transaction_info: { + source: 'route', + }, + }); +}); diff --git a/packages/tanstackstart-react/src/client/index.ts b/packages/tanstackstart-react/src/client/index.ts index 2299b46b7d64..ba0133668fa5 100644 --- a/packages/tanstackstart-react/src/client/index.ts +++ b/packages/tanstackstart-react/src/client/index.ts @@ -4,3 +4,4 @@ export * from '@sentry/react'; export { init } from './sdk'; +export type { TanStackStartBrowserOptions as BrowserOptions } from './sdk'; diff --git a/packages/tanstackstart-react/src/client/sdk.ts b/packages/tanstackstart-react/src/client/sdk.ts index b0ee3b53053f..a3189a62ff92 100644 --- a/packages/tanstackstart-react/src/client/sdk.ts +++ b/packages/tanstackstart-react/src/client/sdk.ts @@ -1,16 +1,28 @@ -import type { Client } from '@sentry/core'; +import type { Client, Integration } from '@sentry/core'; import { applySdkMetadata } from '@sentry/core'; import type { BrowserOptions as ReactBrowserOptions } from '@sentry/react'; -import { getDefaultIntegrations as getReactDefaultIntegrations, init as initReactSDK } from '@sentry/react'; +import { + getDefaultIntegrations as getReactDefaultIntegrations, + init as initReactSDK, + tanstackRouterBrowserTracingIntegration, +} from '@sentry/react'; + +// Treeshakable guard to remove all code related to tracing +declare const __SENTRY_TRACING__: boolean; + +export type TanStackStartBrowserOptions = ReactBrowserOptions & { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + router?: any; +}; /** * Initializes the TanStack Start React SDK * * @param options Configuration options for the SDK. */ -export function init(options: ReactBrowserOptions): Client | undefined { - const sentryOptions: ReactBrowserOptions = { - defaultIntegrations: [...getReactDefaultIntegrations(options)], +export function init(options: TanStackStartBrowserOptions): Client | undefined { + const sentryOptions: TanStackStartBrowserOptions = { + defaultIntegrations: getDefaultIntegrations(options), ...options, }; @@ -18,3 +30,17 @@ export function init(options: ReactBrowserOptions): Client | undefined { return initReactSDK(sentryOptions); } + +function getDefaultIntegrations(options: TanStackStartBrowserOptions): Integration[] { + const integrations = getReactDefaultIntegrations(options); + + // This evaluates to true unless __SENTRY_TRACING__ is text-replaced with "false", + // in which case everything inside will get tree-shaken away + if (typeof __SENTRY_TRACING__ === 'undefined' || __SENTRY_TRACING__) { + if (options.router) { + integrations.push(tanstackRouterBrowserTracingIntegration(options.router)); + } + } + + return integrations; +}