From 244acf1cd6229a90ecb921c1e0c78cc396aeafbf Mon Sep 17 00:00:00 2001 From: Onur Temizkan Date: Wed, 31 Jan 2024 11:07:29 +0000 Subject: [PATCH 1/8] feat(remix): Add `remixBrowserTracingIntegration` --- .github/workflows/build.yml | 2 + .../create-remix-app-v2/remix.config.js | 1 + packages/remix/README.md | 39 ++-- packages/remix/package.json | 5 +- .../src/client/browserTracingIntegration.ts | 41 ++++ packages/remix/src/client/performance.tsx | 207 +++++++++++++----- packages/remix/src/index.client.tsx | 19 +- packages/remix/src/index.server.ts | 1 + .../entry.client.tsx | 12 + .../entry.server.tsx | 30 +++ .../app_v2_tracingIntegration/root.tsx | 73 ++++++ .../routes/action-json-response.$id.tsx | 2 + .../routes/capture-exception.tsx | 2 + .../routes/capture-message.tsx | 2 + .../routes/error-boundary-capture.$id.tsx | 2 + .../routes/index.tsx | 2 + .../routes/loader-defer-response.$id.tsx | 2 + .../routes/loader-json-response.$id.tsx | 2 + .../routes/loader-throw-response.$id.tsx | 2 + .../routes/manual-tracing.$id.tsx | 2 + .../routes/scope-bleed.$id.tsx | 2 + .../server-side-unexpected-errors.$id.tsx | 2 + .../routes/ssr-error.tsx | 2 + .../routes/throw-redirect.tsx | 2 + .../remix/test/integration/remix.config.js | 3 +- 25 files changed, 379 insertions(+), 80 deletions(-) create mode 100644 packages/remix/src/client/browserTracingIntegration.ts create mode 100644 packages/remix/test/integration/app_v2_tracingIntegration/entry.client.tsx create mode 100644 packages/remix/test/integration/app_v2_tracingIntegration/entry.server.tsx create mode 100644 packages/remix/test/integration/app_v2_tracingIntegration/root.tsx create mode 100644 packages/remix/test/integration/app_v2_tracingIntegration/routes/action-json-response.$id.tsx create mode 100644 packages/remix/test/integration/app_v2_tracingIntegration/routes/capture-exception.tsx create mode 100644 packages/remix/test/integration/app_v2_tracingIntegration/routes/capture-message.tsx create mode 100644 packages/remix/test/integration/app_v2_tracingIntegration/routes/error-boundary-capture.$id.tsx create mode 100644 packages/remix/test/integration/app_v2_tracingIntegration/routes/index.tsx create mode 100644 packages/remix/test/integration/app_v2_tracingIntegration/routes/loader-defer-response.$id.tsx create mode 100644 packages/remix/test/integration/app_v2_tracingIntegration/routes/loader-json-response.$id.tsx create mode 100644 packages/remix/test/integration/app_v2_tracingIntegration/routes/loader-throw-response.$id.tsx create mode 100644 packages/remix/test/integration/app_v2_tracingIntegration/routes/manual-tracing.$id.tsx create mode 100644 packages/remix/test/integration/app_v2_tracingIntegration/routes/scope-bleed.$id.tsx create mode 100644 packages/remix/test/integration/app_v2_tracingIntegration/routes/server-side-unexpected-errors.$id.tsx create mode 100644 packages/remix/test/integration/app_v2_tracingIntegration/routes/ssr-error.tsx create mode 100644 packages/remix/test/integration/app_v2_tracingIntegration/routes/throw-redirect.tsx diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c87ef1782865..999e290dcf50 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -906,6 +906,7 @@ jobs: matrix: node: [18, 20, 21] remix: [1, 2] + tracingIntegration: [false, true] # Remix v2 only supports Node 18+, so run Node 14, 16 tests separately include: - node: 14 @@ -929,6 +930,7 @@ jobs: env: NODE_VERSION: ${{ matrix.node }} REMIX_VERSION: ${{ matrix.remix }} + TRACING_INTEGRATION: ${{ matrix.tracingIntegration }} run: | cd packages/remix yarn test:integration:ci diff --git a/dev-packages/e2e-tests/test-applications/create-remix-app-v2/remix.config.js b/dev-packages/e2e-tests/test-applications/create-remix-app-v2/remix.config.js index cb3c8c7a9fb7..92ed1ddc32eb 100644 --- a/dev-packages/e2e-tests/test-applications/create-remix-app-v2/remix.config.js +++ b/dev-packages/e2e-tests/test-applications/create-remix-app-v2/remix.config.js @@ -6,4 +6,5 @@ module.exports = { // serverBuildPath: 'build/index.js', // publicPath: '/build/', serverModuleFormat: 'cjs', + entry, }; diff --git a/packages/remix/README.md b/packages/remix/README.md index c51820980e91..9903dc6bf0bd 100644 --- a/packages/remix/README.md +++ b/packages/remix/README.md @@ -12,27 +12,26 @@ ## General -This package is a wrapper around `@sentry/node` for the server and `@sentry/react` for the client, with added functionality related to Remix. +This package is a wrapper around `@sentry/node` for the server and `@sentry/react` for the client, with added +functionality related to Remix. To use this SDK, initialize Sentry in your Remix entry points for both the client and server. ```ts // entry.client.tsx -import { useLocation, useMatches } from "@remix-run/react"; -import * as Sentry from "@sentry/remix"; -import { useEffect } from "react"; +import { useLocation, useMatches } from '@remix-run/react'; +import * as Sentry from '@sentry/remix'; +import { useEffect } from 'react'; Sentry.init({ - dsn: "__DSN__", + dsn: '__DSN__', tracesSampleRate: 1, integrations: [ - new Sentry.BrowserTracing({ - routingInstrumentation: Sentry.remixRouterInstrumentation( - useEffect, - useLocation, - useMatches, - ), + Sentry.remixBrowserTracingIntegration({ + useEffect, + useLocation, + useMatches, }), ], // ... @@ -42,19 +41,20 @@ Sentry.init({ ```ts // entry.server.tsx -import { prisma } from "~/db.server"; +import { prisma } from '~/db.server'; -import * as Sentry from "@sentry/remix"; +import * as Sentry from '@sentry/remix'; Sentry.init({ - dsn: "__DSN__", + dsn: '__DSN__', tracesSampleRate: 1, integrations: [new Sentry.Integrations.Prisma({ client: prisma })], // ... }); ``` -Also, wrap your Remix root with `withSentry` to catch React component errors and to get parameterized router transactions. +Also, wrap your Remix root with `withSentry` to catch React component errors and to get parameterized router +transactions. ```ts // root.tsx @@ -139,8 +139,11 @@ Sentry.captureEvent({ ## Sourcemaps and Releases -The Remix SDK provides a script that automatically creates a release and uploads sourcemaps. To generate sourcemaps with Remix, you need to call `remix build` with the `--sourcemap` option. +The Remix SDK provides a script that automatically creates a release and uploads sourcemaps. To generate sourcemaps with +Remix, you need to call `remix build` with the `--sourcemap` option. -On release, call `sentry-upload-sourcemaps` to upload source maps and create a release. To see more details on how to use the command, call `sentry-upload-sourcemaps --help`. +On release, call `sentry-upload-sourcemaps` to upload source maps and create a release. To see more details on how to +use the command, call `sentry-upload-sourcemaps --help`. -For more advanced configuration, [directly use `sentry-cli` to upload source maps.](https://github.com/getsentry/sentry-cli). +For more advanced configuration, +[directly use `sentry-cli` to upload source maps.](https://github.com/getsentry/sentry-cli). diff --git a/packages/remix/package.json b/packages/remix/package.json index b9e22128ece4..8fdfc58b1afb 100644 --- a/packages/remix/package.json +++ b/packages/remix/package.json @@ -70,11 +70,12 @@ "fix": "eslint . --format stylish --fix", "lint": "eslint . --format stylish", "test": "yarn test:unit", - "test:integration": "run-s test:integration:v1 test:integration:v2", + "test:integration": "run-s test:integration:v1 test:integration:v2 test:integration:tracingIntegration", "test:integration:v1": "run-s test:integration:clean test:integration:prepare test:integration:client test:integration:server", "test:integration:v2": "export REMIX_VERSION=2 && run-s test:integration:v1", + "test:integration:tracingIntegration": "export TRACING_INTEGRATION=true && run-s test:integration:v2", "test:integration:ci": "run-s test:integration:clean test:integration:prepare test:integration:client:ci test:integration:server", - "test:integration:prepare": "(cd test/integration && yarn)", + "test:integration:prepare": "(cd test/integration && yarn install --force)", "test:integration:clean": "(cd test/integration && rimraf .cache node_modules build)", "test:integration:client": "yarn playwright install-deps && yarn playwright test test/integration/test/client/ --project='chromium'", "test:integration:client:ci": "yarn test:integration:client --reporter='line'", diff --git a/packages/remix/src/client/browserTracingIntegration.ts b/packages/remix/src/client/browserTracingIntegration.ts new file mode 100644 index 000000000000..5d0dcf2cbee3 --- /dev/null +++ b/packages/remix/src/client/browserTracingIntegration.ts @@ -0,0 +1,41 @@ +import { browserTracingIntegration as originalBrowserTracingIntegration } from '@sentry/react'; +import type { Integration } from '@sentry/types'; +import { setGlobals, startPageloadSpan } from './performance'; +import type { RemixBrowserTracingIntegrationOptions } from './performance'; +/** + * Creates a browser tracing integration for Remix applications. + * This integration will create pageload and navigation spans. + */ +export function remixBrowserTracingIntegration(options: RemixBrowserTracingIntegrationOptions): Integration { + if (options.startTransactionOnPageLoad === undefined) { + options.startTransactionOnPageLoad = true; + } + + if (options.startTransactionOnLocationChange === undefined) { + options.startTransactionOnLocationChange = true; + } + + setGlobals({ + useEffect: options.useEffect, + useLocation: options.useLocation, + useMatches: options.useMatches, + startTransactionOnLocationChange: options.startTransactionOnLocationChange, + }); + + const browserTracingIntegrationInstance = originalBrowserTracingIntegration({ + ...options, + instrumentPageLoad: false, + instrumentNavigation: false, + }); + + return { + ...browserTracingIntegrationInstance, + afterAllSetup(client) { + browserTracingIntegrationInstance.afterAllSetup?.(client); + + if (options.startTransactionOnPageLoad) { + startPageloadSpan(); + } + }, + }; +} diff --git a/packages/remix/src/client/performance.tsx b/packages/remix/src/client/performance.tsx index fc395e8ddedc..7d3ed2558095 100644 --- a/packages/remix/src/client/performance.tsx +++ b/packages/remix/src/client/performance.tsx @@ -1,46 +1,62 @@ -import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core'; -import type { ErrorBoundaryProps } from '@sentry/react'; -import { WINDOW, withErrorBoundary } from '@sentry/react'; -import type { Transaction, TransactionContext } from '@sentry/types'; +import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, getActiveSpan, getRootSpan } from '@sentry/core'; +import type { browserTracingIntegration as originalBrowserTracingIntegration } from '@sentry/react'; +import type { BrowserClient, ErrorBoundaryProps } from '@sentry/react'; +import { + WINDOW, + getClient, + startBrowserTracingNavigationSpan, + startBrowserTracingPageLoadSpan, + withErrorBoundary, +} from '@sentry/react'; +import type { Span, Transaction, TransactionContext } from '@sentry/types'; import { isNodeEnv, logger } from '@sentry/utils'; import * as React from 'react'; import { DEBUG_BUILD } from '../utils/debug-build'; import { getFutureFlagsBrowser, readRemixVersionFromLoader } from '../utils/futureFlags'; -const DEFAULT_TAGS = { - 'routing.instrumentation': 'remix-router', -} as const; - -type Params = { +export type Params = { readonly [key in Key]: string | undefined; }; -interface RouteMatch { +export interface RouteMatch { params: Params; pathname: string; id: string; handle: unknown; } +export type UseEffect = (cb: () => void, deps: unknown[]) => void; -type UseEffect = (cb: () => void, deps: unknown[]) => void; -type UseLocation = () => { +export type UseLocation = () => { pathname: string; search?: string; hash?: string; state?: unknown; key?: unknown; }; -type UseMatches = () => RouteMatch[] | null; -let activeTransaction: Transaction | undefined; +export type UseMatches = () => RouteMatch[] | null; + +export type RemixBrowserTracingIntegrationOptions = Partial[0]> & { + useEffect?: UseEffect; + useLocation?: UseLocation; + useMatches?: UseMatches; + startTransactionOnPageLoad?: boolean; + startTransactionOnLocationChange?: boolean; +}; + +const DEFAULT_TAGS = { + 'routing.instrumentation': 'remix-router', +} as const; + +let activeRootSpan: Span | undefined; -let _useEffect: UseEffect; -let _useLocation: UseLocation; -let _useMatches: UseMatches; +let _useEffect: UseEffect | undefined; +let _useLocation: UseLocation | undefined; +let _useMatches: UseMatches | undefined; -let _customStartTransaction: (context: TransactionContext) => Transaction | undefined; -let _startTransactionOnLocationChange: boolean; +let _customStartTransaction: ((context: TransactionContext) => Span | undefined) | undefined; +let _startTransactionOnLocationChange: boolean | undefined; function getInitPathName(): string | undefined { if (WINDOW && WINDOW.location) { @@ -54,11 +70,85 @@ function isRemixV2(remixVersion: number | undefined): boolean { return remixVersion === 2 || getFutureFlagsBrowser()?.v2_errorBoundary || false; } +export function startPageloadSpan(): void { + const initPathName = getInitPathName(); + + if (!initPathName) { + return; + } + + // If _customStartTransaction is not defined, we know that we are using the browserTracingIntegration + if (!_customStartTransaction) { + const client = getClient(); + + if (!client) { + return; + } + + startBrowserTracingPageLoadSpan(client, { + name: initPathName, + op: 'pageload', + origin: 'auto.pageload.remix', + tags: DEFAULT_TAGS, + metadata: { + source: 'url', + }, + }); + + activeRootSpan = getActiveSpan(); + } else { + activeRootSpan = _customStartTransaction({ + name: initPathName, + op: 'pageload', + origin: 'auto.pageload.remix', + tags: DEFAULT_TAGS, + metadata: { + source: 'url', + }, + }); + } +} + +function startNavigationSpan(matches: RouteMatch[]): void { + // If _customStartTransaction is not defined, we know that we are using the browserTracingIntegration + if (!_customStartTransaction) { + const client = getClient(); + + if (!client) { + return; + } + + startBrowserTracingNavigationSpan(client, { + name: matches[matches.length - 1].id, + op: 'navigation', + origin: 'auto.navigation.remix', + tags: DEFAULT_TAGS, + metadata: { + source: 'route', + }, + }); + + activeRootSpan = getActiveSpan(); + } else { + activeRootSpan = _customStartTransaction({ + name: matches[matches.length - 1].id, + op: 'navigation', + origin: 'auto.navigation.remix', + tags: DEFAULT_TAGS, + metadata: { + source: 'route', + }, + }); + } +} + /** * Creates a react-router v6 instrumention for Remix applications. * * This implementation is slightly different (and simpler) from the react-router instrumentation * as in Remix, `useMatches` hook is available where in react-router-v6 it's not yet. + * + * @deprecated Use `remixBrowserTracingIntegration` instead. */ export function remixRouterInstrumentation(useEffect: UseEffect, useLocation: UseLocation, useMatches: UseMatches) { return ( @@ -66,25 +156,17 @@ export function remixRouterInstrumentation(useEffect: UseEffect, useLocation: Us startTransactionOnPageLoad = true, startTransactionOnLocationChange = true, ): void => { - const initPathName = getInitPathName(); - if (startTransactionOnPageLoad && initPathName) { - activeTransaction = customStartTransaction({ - name: initPathName, - op: 'pageload', - origin: 'auto.pageload.remix', - tags: DEFAULT_TAGS, - metadata: { - source: 'url', - }, - }); - } + setGlobals({ + useEffect, + useLocation, + useMatches, + startTransactionOnLocationChange, + customStartTransaction, + }); - _useEffect = useEffect; - _useLocation = useLocation; - _useMatches = useMatches; - - _customStartTransaction = customStartTransaction; - _startTransactionOnLocationChange = startTransactionOnLocationChange; + if (startTransactionOnPageLoad) { + startPageloadSpan(); + } }; } @@ -109,7 +191,7 @@ export function withSentry

, R extends React.Co ): R { const SentryRoot: React.FC

= (props: P) => { // Early return when any of the required functions is not available. - if (!_useEffect || !_useLocation || !_useMatches || !_customStartTransaction) { + if (!_useEffect || !_useLocation || !_useMatches) { DEBUG_BUILD && !isNodeEnv() && logger.warn('Remix SDK was unable to wrap your root because of one or more missing parameters.'); @@ -125,9 +207,14 @@ export function withSentry

, R extends React.Co const matches = _useMatches(); _useEffect(() => { - if (activeTransaction && matches && matches.length) { - activeTransaction.updateName(matches[matches.length - 1].id); - activeTransaction.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'route'); + const activeRootSpan = getActiveSpan(); + if (activeRootSpan && matches && matches.length) { + const transaction = getRootSpan(activeRootSpan); + + if (transaction) { + transaction.updateName(matches[matches.length - 1].id); + transaction.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'route'); + } } isBaseLocation = true; @@ -135,27 +222,19 @@ export function withSentry

, R extends React.Co _useEffect(() => { if (isBaseLocation) { - if (activeTransaction) { - activeTransaction.end(); + if (activeRootSpan) { + activeRootSpan.end(); } return; } if (_startTransactionOnLocationChange && matches && matches.length) { - if (activeTransaction) { - activeTransaction.end(); + if (activeRootSpan) { + activeRootSpan.end(); } - activeTransaction = _customStartTransaction({ - name: matches[matches.length - 1].id, - op: 'navigation', - origin: 'auto.navigation.remix', - tags: DEFAULT_TAGS, - metadata: { - source: 'route', - }, - }); + startNavigationSpan(matches); } }, [location]); @@ -175,3 +254,23 @@ export function withSentry

, R extends React.Co // will break advanced type inference done by react router params return SentryRoot; } + +export function setGlobals({ + useEffect, + useLocation, + useMatches, + startTransactionOnLocationChange, + customStartTransaction, +}: { + useEffect?: UseEffect; + useLocation?: UseLocation; + useMatches?: UseMatches; + startTransactionOnLocationChange?: boolean; + customStartTransaction?: (context: TransactionContext) => Span | undefined; +}): void { + _useEffect = useEffect; + _useLocation = useLocation; + _useMatches = useMatches; + _startTransactionOnLocationChange = startTransactionOnLocationChange; + _customStartTransaction = customStartTransaction; +} diff --git a/packages/remix/src/index.client.tsx b/packages/remix/src/index.client.tsx index 9c619ff1d851..8fd7d87c5e5a 100644 --- a/packages/remix/src/index.client.tsx +++ b/packages/remix/src/index.client.tsx @@ -1,16 +1,25 @@ import { applySdkMetadata } from '@sentry/core'; import { getCurrentScope, init as reactInit } from '@sentry/react'; - import type { RemixOptions } from './utils/remixOptions'; -export { remixRouterInstrumentation, withSentry } from './client/performance'; export { captureRemixErrorBoundaryError } from './client/errors'; +export { + remixRouterInstrumentation, + withSentry, +} from './client/performance'; + +export { remixBrowserTracingIntegration } from './client/browserTracingIntegration'; + export * from '@sentry/react'; export function init(options: RemixOptions): void { - applySdkMetadata(options, 'remix', ['remix', 'react']); - options.environment = options.environment || process.env.NODE_ENV; + const opts = { + ...options, + environment: options.environment || process.env.NODE_ENV, + }; + + applySdkMetadata(opts, 'remix', ['remix', 'react']); - reactInit(options); + reactInit(opts); getCurrentScope().setTag('runtime', 'browser'); } diff --git a/packages/remix/src/index.server.ts b/packages/remix/src/index.server.ts index 674beed61ee6..7ff864669478 100644 --- a/packages/remix/src/index.server.ts +++ b/packages/remix/src/index.server.ts @@ -113,6 +113,7 @@ export { captureRemixServerException, wrapRemixHandleError } from './utils/instr export { ErrorBoundary, withErrorBoundary } from '@sentry/react'; export { remixRouterInstrumentation, withSentry } from './client/performance'; export { captureRemixErrorBoundaryError } from './client/errors'; +export { remixBrowserTracingIntegration } from './client/browserTracingIntegration'; export { wrapExpressCreateRequestHandler } from './utils/serverAdapters/express'; export type { SentryMetaArgs } from './utils/types'; diff --git a/packages/remix/test/integration/app_v2_tracingIntegration/entry.client.tsx b/packages/remix/test/integration/app_v2_tracingIntegration/entry.client.tsx new file mode 100644 index 000000000000..27b66240a474 --- /dev/null +++ b/packages/remix/test/integration/app_v2_tracingIntegration/entry.client.tsx @@ -0,0 +1,12 @@ +import { RemixBrowser, useLocation, useMatches } from '@remix-run/react'; +import * as Sentry from '@sentry/remix'; +import { useEffect } from 'react'; +import { hydrate } from 'react-dom'; + +Sentry.init({ + dsn: 'https://public@dsn.ingest.sentry.io/1337', + tracesSampleRate: 1, + integrations: [Sentry.remixBrowserTracingIntegration({ useEffect, useLocation, useMatches })], +}); + +hydrate(, document); diff --git a/packages/remix/test/integration/app_v2_tracingIntegration/entry.server.tsx b/packages/remix/test/integration/app_v2_tracingIntegration/entry.server.tsx new file mode 100644 index 000000000000..bba366801092 --- /dev/null +++ b/packages/remix/test/integration/app_v2_tracingIntegration/entry.server.tsx @@ -0,0 +1,30 @@ +import type { EntryContext } from '@remix-run/node'; +import { RemixServer } from '@remix-run/react'; +import * as Sentry from '@sentry/remix'; +import { renderToString } from 'react-dom/server'; + +Sentry.init({ + dsn: 'https://public@dsn.ingest.sentry.io/1337', + tracesSampleRate: 1, + tracePropagationTargets: ['example.org'], + // Disabling to test series of envelopes deterministically. + autoSessionTracking: false, +}); + +export const handleError = Sentry.wrapRemixHandleError; + +export default function handleRequest( + request: Request, + responseStatusCode: number, + responseHeaders: Headers, + remixContext: EntryContext, +) { + let markup = renderToString(); + + responseHeaders.set('Content-Type', 'text/html'); + + return new Response('' + markup, { + status: responseStatusCode, + headers: responseHeaders, + }); +} diff --git a/packages/remix/test/integration/app_v2_tracingIntegration/root.tsx b/packages/remix/test/integration/app_v2_tracingIntegration/root.tsx new file mode 100644 index 000000000000..15b78b8a6325 --- /dev/null +++ b/packages/remix/test/integration/app_v2_tracingIntegration/root.tsx @@ -0,0 +1,73 @@ +import { LoaderFunction, V2_MetaFunction, defer, json, redirect } from '@remix-run/node'; +import { Links, LiveReload, Meta, Outlet, Scripts, ScrollRestoration, useRouteError } from '@remix-run/react'; +import { V2_ErrorBoundaryComponent } from '@remix-run/react/dist/routeModules'; +import { captureRemixErrorBoundaryError, withSentry } from '@sentry/remix'; + +export const ErrorBoundary: V2_ErrorBoundaryComponent = () => { + const error = useRouteError(); + + captureRemixErrorBoundaryError(error); + + return

error
; +}; + +export const meta: V2_MetaFunction = ({ data }) => [ + { charset: 'utf-8' }, + { title: 'New Remix App' }, + { name: 'viewport', content: 'width=device-width,initial-scale=1' }, + { name: 'sentry-trace', content: data.sentryTrace }, + { name: 'baggage', content: data.sentryBaggage }, +]; + +export const loader: LoaderFunction = async ({ request }) => { + const url = new URL(request.url); + const type = url.searchParams.get('type'); + + switch (type) { + case 'empty': + return {}; + case 'plain': + return { + data_one: [], + data_two: 'a string', + }; + case 'json': + return json({ data_one: [], data_two: 'a string' }, { headers: { 'Cache-Control': 'max-age=300' } }); + case 'defer': + return defer({ data_one: [], data_two: 'a string' }); + case 'null': + return null; + case 'undefined': + return undefined; + case 'throwRedirect': + throw redirect('/?type=plain'); + case 'returnRedirect': + return redirect('/?type=plain'); + case 'throwRedirectToExternal': + throw redirect('https://example.com'); + case 'returnRedirectToExternal': + return redirect('https://example.com'); + default: { + return {}; + } + } +}; + +function App() { + return ( + + + + + + + + + + + + + ); +} + +export default withSentry(App); diff --git a/packages/remix/test/integration/app_v2_tracingIntegration/routes/action-json-response.$id.tsx b/packages/remix/test/integration/app_v2_tracingIntegration/routes/action-json-response.$id.tsx new file mode 100644 index 000000000000..7a00bfb2bfe7 --- /dev/null +++ b/packages/remix/test/integration/app_v2_tracingIntegration/routes/action-json-response.$id.tsx @@ -0,0 +1,2 @@ +export * from '../../common/routes/action-json-response.$id'; +export { default } from '../../common/routes/action-json-response.$id'; diff --git a/packages/remix/test/integration/app_v2_tracingIntegration/routes/capture-exception.tsx b/packages/remix/test/integration/app_v2_tracingIntegration/routes/capture-exception.tsx new file mode 100644 index 000000000000..1ba745d2e63d --- /dev/null +++ b/packages/remix/test/integration/app_v2_tracingIntegration/routes/capture-exception.tsx @@ -0,0 +1,2 @@ +export * from '../../common/routes/capture-exception'; +export { default } from '../../common/routes/capture-exception'; diff --git a/packages/remix/test/integration/app_v2_tracingIntegration/routes/capture-message.tsx b/packages/remix/test/integration/app_v2_tracingIntegration/routes/capture-message.tsx new file mode 100644 index 000000000000..9dae2318cc14 --- /dev/null +++ b/packages/remix/test/integration/app_v2_tracingIntegration/routes/capture-message.tsx @@ -0,0 +1,2 @@ +export * from '../../common/routes/capture-message'; +export { default } from '../../common/routes/capture-message'; diff --git a/packages/remix/test/integration/app_v2_tracingIntegration/routes/error-boundary-capture.$id.tsx b/packages/remix/test/integration/app_v2_tracingIntegration/routes/error-boundary-capture.$id.tsx new file mode 100644 index 000000000000..011f92462069 --- /dev/null +++ b/packages/remix/test/integration/app_v2_tracingIntegration/routes/error-boundary-capture.$id.tsx @@ -0,0 +1,2 @@ +export * from '../../common/routes/error-boundary-capture.$id'; +export { default } from '../../common/routes/error-boundary-capture.$id'; diff --git a/packages/remix/test/integration/app_v2_tracingIntegration/routes/index.tsx b/packages/remix/test/integration/app_v2_tracingIntegration/routes/index.tsx new file mode 100644 index 000000000000..22c086a4c2cf --- /dev/null +++ b/packages/remix/test/integration/app_v2_tracingIntegration/routes/index.tsx @@ -0,0 +1,2 @@ +export * from '../../common/routes/index'; +export { default } from '../../common/routes/index'; diff --git a/packages/remix/test/integration/app_v2_tracingIntegration/routes/loader-defer-response.$id.tsx b/packages/remix/test/integration/app_v2_tracingIntegration/routes/loader-defer-response.$id.tsx new file mode 100644 index 000000000000..69499e594ccc --- /dev/null +++ b/packages/remix/test/integration/app_v2_tracingIntegration/routes/loader-defer-response.$id.tsx @@ -0,0 +1,2 @@ +export * from '../../common/routes/loader-defer-response.$id'; +export { default } from '../../common/routes/loader-defer-response.$id'; diff --git a/packages/remix/test/integration/app_v2_tracingIntegration/routes/loader-json-response.$id.tsx b/packages/remix/test/integration/app_v2_tracingIntegration/routes/loader-json-response.$id.tsx new file mode 100644 index 000000000000..7761875bdb76 --- /dev/null +++ b/packages/remix/test/integration/app_v2_tracingIntegration/routes/loader-json-response.$id.tsx @@ -0,0 +1,2 @@ +export * from '../../common/routes/loader-json-response.$id'; +export { default } from '../../common/routes/loader-json-response.$id'; diff --git a/packages/remix/test/integration/app_v2_tracingIntegration/routes/loader-throw-response.$id.tsx b/packages/remix/test/integration/app_v2_tracingIntegration/routes/loader-throw-response.$id.tsx new file mode 100644 index 000000000000..6b9a6a85cbef --- /dev/null +++ b/packages/remix/test/integration/app_v2_tracingIntegration/routes/loader-throw-response.$id.tsx @@ -0,0 +1,2 @@ +export * from '../../common/routes/loader-throw-response.$id'; +export { default } from '../../common/routes/loader-throw-response.$id'; diff --git a/packages/remix/test/integration/app_v2_tracingIntegration/routes/manual-tracing.$id.tsx b/packages/remix/test/integration/app_v2_tracingIntegration/routes/manual-tracing.$id.tsx new file mode 100644 index 000000000000..a7cfebe4ed46 --- /dev/null +++ b/packages/remix/test/integration/app_v2_tracingIntegration/routes/manual-tracing.$id.tsx @@ -0,0 +1,2 @@ +export * from '../../common/routes/manual-tracing.$id'; +export { default } from '../../common/routes/manual-tracing.$id'; diff --git a/packages/remix/test/integration/app_v2_tracingIntegration/routes/scope-bleed.$id.tsx b/packages/remix/test/integration/app_v2_tracingIntegration/routes/scope-bleed.$id.tsx new file mode 100644 index 000000000000..5ba2376f0339 --- /dev/null +++ b/packages/remix/test/integration/app_v2_tracingIntegration/routes/scope-bleed.$id.tsx @@ -0,0 +1,2 @@ +export * from '../../common/routes/scope-bleed.$id'; +export { default } from '../../common/routes/scope-bleed.$id'; diff --git a/packages/remix/test/integration/app_v2_tracingIntegration/routes/server-side-unexpected-errors.$id.tsx b/packages/remix/test/integration/app_v2_tracingIntegration/routes/server-side-unexpected-errors.$id.tsx new file mode 100644 index 000000000000..d9571c68ddd5 --- /dev/null +++ b/packages/remix/test/integration/app_v2_tracingIntegration/routes/server-side-unexpected-errors.$id.tsx @@ -0,0 +1,2 @@ +export * from '../../common/routes/server-side-unexpected-errors.$id'; +export { default } from '../../common/routes/server-side-unexpected-errors.$id'; diff --git a/packages/remix/test/integration/app_v2_tracingIntegration/routes/ssr-error.tsx b/packages/remix/test/integration/app_v2_tracingIntegration/routes/ssr-error.tsx new file mode 100644 index 000000000000..627f7e126871 --- /dev/null +++ b/packages/remix/test/integration/app_v2_tracingIntegration/routes/ssr-error.tsx @@ -0,0 +1,2 @@ +export * from '../../common/routes/ssr-error'; +export { default } from '../../common/routes/ssr-error'; diff --git a/packages/remix/test/integration/app_v2_tracingIntegration/routes/throw-redirect.tsx b/packages/remix/test/integration/app_v2_tracingIntegration/routes/throw-redirect.tsx new file mode 100644 index 000000000000..4425f3432b58 --- /dev/null +++ b/packages/remix/test/integration/app_v2_tracingIntegration/routes/throw-redirect.tsx @@ -0,0 +1,2 @@ +export * from '../../common/routes/throw-redirect'; +export { default } from '../../common/routes/throw-redirect'; diff --git a/packages/remix/test/integration/remix.config.js b/packages/remix/test/integration/remix.config.js index b4c7ac0837b8..418d3690f696 100644 --- a/packages/remix/test/integration/remix.config.js +++ b/packages/remix/test/integration/remix.config.js @@ -1,8 +1,9 @@ /** @type {import('@remix-run/dev').AppConfig} */ const useV2 = process.env.REMIX_VERSION === '2'; +const useBrowserTracing = process.env.TRACING_INTEGRATION === 'true'; module.exports = { - appDirectory: useV2 ? 'app_v2' : 'app_v1', + appDirectory: useBrowserTracing ? 'app_v2_tracingIntegration' : useV2 ? 'app_v2' : 'app_v1', assetsBuildDirectory: 'public/build', serverBuildPath: 'build/index.js', publicPath: '/build/', From c2a2a433c929a5336e29e7e6dc5dbd357b1be9da Mon Sep 17 00:00:00 2001 From: Onur Temizkan Date: Wed, 31 Jan 2024 15:30:17 +0000 Subject: [PATCH 2/8] Rename integration to `browserTracingIntegration` --- packages/remix/README.md | 2 +- packages/remix/src/client/browserTracingIntegration.ts | 2 +- packages/remix/src/client/performance.tsx | 2 +- packages/remix/src/index.client.tsx | 2 +- packages/remix/src/index.server.ts | 2 +- .../test/integration/app_v2_tracingIntegration/entry.client.tsx | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/remix/README.md b/packages/remix/README.md index 9903dc6bf0bd..ae2dfbeff53a 100644 --- a/packages/remix/README.md +++ b/packages/remix/README.md @@ -28,7 +28,7 @@ Sentry.init({ dsn: '__DSN__', tracesSampleRate: 1, integrations: [ - Sentry.remixBrowserTracingIntegration({ + Sentry.browserTracingIntegration({ useEffect, useLocation, useMatches, diff --git a/packages/remix/src/client/browserTracingIntegration.ts b/packages/remix/src/client/browserTracingIntegration.ts index 5d0dcf2cbee3..cb14b86f4f4d 100644 --- a/packages/remix/src/client/browserTracingIntegration.ts +++ b/packages/remix/src/client/browserTracingIntegration.ts @@ -6,7 +6,7 @@ import type { RemixBrowserTracingIntegrationOptions } from './performance'; * Creates a browser tracing integration for Remix applications. * This integration will create pageload and navigation spans. */ -export function remixBrowserTracingIntegration(options: RemixBrowserTracingIntegrationOptions): Integration { +export function browserTracingIntegration(options: RemixBrowserTracingIntegrationOptions): Integration { if (options.startTransactionOnPageLoad === undefined) { options.startTransactionOnPageLoad = true; } diff --git a/packages/remix/src/client/performance.tsx b/packages/remix/src/client/performance.tsx index 7d3ed2558095..1efe417bde92 100644 --- a/packages/remix/src/client/performance.tsx +++ b/packages/remix/src/client/performance.tsx @@ -148,7 +148,7 @@ function startNavigationSpan(matches: RouteMatch[]): void { * This implementation is slightly different (and simpler) from the react-router instrumentation * as in Remix, `useMatches` hook is available where in react-router-v6 it's not yet. * - * @deprecated Use `remixBrowserTracingIntegration` instead. + * @deprecated Use `browserTracingIntegration` instead. */ export function remixRouterInstrumentation(useEffect: UseEffect, useLocation: UseLocation, useMatches: UseMatches) { return ( diff --git a/packages/remix/src/index.client.tsx b/packages/remix/src/index.client.tsx index 8fd7d87c5e5a..3a56684c592f 100644 --- a/packages/remix/src/index.client.tsx +++ b/packages/remix/src/index.client.tsx @@ -7,7 +7,7 @@ export { withSentry, } from './client/performance'; -export { remixBrowserTracingIntegration } from './client/browserTracingIntegration'; +export { browserTracingIntegration } from './client/browserTracingIntegration'; export * from '@sentry/react'; diff --git a/packages/remix/src/index.server.ts b/packages/remix/src/index.server.ts index 7ff864669478..c0684a2c84e3 100644 --- a/packages/remix/src/index.server.ts +++ b/packages/remix/src/index.server.ts @@ -113,7 +113,7 @@ export { captureRemixServerException, wrapRemixHandleError } from './utils/instr export { ErrorBoundary, withErrorBoundary } from '@sentry/react'; export { remixRouterInstrumentation, withSentry } from './client/performance'; export { captureRemixErrorBoundaryError } from './client/errors'; -export { remixBrowserTracingIntegration } from './client/browserTracingIntegration'; +export { browserTracingIntegration } from './client/browserTracingIntegration'; export { wrapExpressCreateRequestHandler } from './utils/serverAdapters/express'; export type { SentryMetaArgs } from './utils/types'; diff --git a/packages/remix/test/integration/app_v2_tracingIntegration/entry.client.tsx b/packages/remix/test/integration/app_v2_tracingIntegration/entry.client.tsx index 27b66240a474..7273433127ac 100644 --- a/packages/remix/test/integration/app_v2_tracingIntegration/entry.client.tsx +++ b/packages/remix/test/integration/app_v2_tracingIntegration/entry.client.tsx @@ -6,7 +6,7 @@ import { hydrate } from 'react-dom'; Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', tracesSampleRate: 1, - integrations: [Sentry.remixBrowserTracingIntegration({ useEffect, useLocation, useMatches })], + integrations: [Sentry.browserTracingIntegration({ useEffect, useLocation, useMatches })], }); hydrate(, document); From 8a3311c0e467ed7b3bbd863eb26091a5a4ddb465 Mon Sep 17 00:00:00 2001 From: Onur Temizkan Date: Wed, 31 Jan 2024 15:36:57 +0000 Subject: [PATCH 3/8] Add deprecation flag to `remixRouterInstrumentation` --- packages/remix/src/client/performance.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/remix/src/client/performance.tsx b/packages/remix/src/client/performance.tsx index 1efe417bde92..efe7584b7ffa 100644 --- a/packages/remix/src/client/performance.tsx +++ b/packages/remix/src/client/performance.tsx @@ -143,12 +143,12 @@ function startNavigationSpan(matches: RouteMatch[]): void { } /** + * @deprecated Use `browserTracingIntegration` instead. + * * Creates a react-router v6 instrumention for Remix applications. * * This implementation is slightly different (and simpler) from the react-router instrumentation * as in Remix, `useMatches` hook is available where in react-router-v6 it's not yet. - * - * @deprecated Use `browserTracingIntegration` instead. */ export function remixRouterInstrumentation(useEffect: UseEffect, useLocation: UseLocation, useMatches: UseMatches) { return ( From e47fcdcc9fcc00e5944dcfd5eb7d0ab64aa0d8af Mon Sep 17 00:00:00 2001 From: Onur Temizkan Date: Thu, 1 Feb 2024 11:42:25 +0000 Subject: [PATCH 4/8] Address review comments. --- .../src/client/browserTracingIntegration.ts | 14 ++-- packages/remix/src/client/performance.tsx | 73 +++++++------------ 2 files changed, 35 insertions(+), 52 deletions(-) diff --git a/packages/remix/src/client/browserTracingIntegration.ts b/packages/remix/src/client/browserTracingIntegration.ts index cb14b86f4f4d..ef6e96bf1fb9 100644 --- a/packages/remix/src/client/browserTracingIntegration.ts +++ b/packages/remix/src/client/browserTracingIntegration.ts @@ -7,19 +7,19 @@ import type { RemixBrowserTracingIntegrationOptions } from './performance'; * This integration will create pageload and navigation spans. */ export function browserTracingIntegration(options: RemixBrowserTracingIntegrationOptions): Integration { - if (options.startTransactionOnPageLoad === undefined) { - options.startTransactionOnPageLoad = true; + if (options.instrumentPageLoad === undefined) { + options.instrumentPageLoad = true; } - if (options.startTransactionOnLocationChange === undefined) { - options.startTransactionOnLocationChange = true; + if (options.instrumentNavigation === undefined) { + options.instrumentNavigation = true; } setGlobals({ useEffect: options.useEffect, useLocation: options.useLocation, useMatches: options.useMatches, - startTransactionOnLocationChange: options.startTransactionOnLocationChange, + startTransactionOnLocationChange: options.instrumentNavigation, }); const browserTracingIntegrationInstance = originalBrowserTracingIntegration({ @@ -31,9 +31,9 @@ export function browserTracingIntegration(options: RemixBrowserTracingIntegratio return { ...browserTracingIntegrationInstance, afterAllSetup(client) { - browserTracingIntegrationInstance.afterAllSetup?.(client); + browserTracingIntegrationInstance.afterAllSetup(client); - if (options.startTransactionOnPageLoad) { + if (options.instrumentPageLoad) { startPageloadSpan(); } }, diff --git a/packages/remix/src/client/performance.tsx b/packages/remix/src/client/performance.tsx index efe7584b7ffa..45bbef4f40c6 100644 --- a/packages/remix/src/client/performance.tsx +++ b/packages/remix/src/client/performance.tsx @@ -8,7 +8,7 @@ import { startBrowserTracingPageLoadSpan, withErrorBoundary, } from '@sentry/react'; -import type { Span, Transaction, TransactionContext } from '@sentry/types'; +import type { Span, StartSpanOptions, Transaction, TransactionContext } from '@sentry/types'; import { isNodeEnv, logger } from '@sentry/utils'; import * as React from 'react'; @@ -41,16 +41,12 @@ export type RemixBrowserTracingIntegrationOptions = Partial(); @@ -85,31 +91,23 @@ export function startPageloadSpan(): void { return; } - startBrowserTracingPageLoadSpan(client, { - name: initPathName, - op: 'pageload', - origin: 'auto.pageload.remix', - tags: DEFAULT_TAGS, - metadata: { - source: 'url', - }, - }); - - activeRootSpan = getActiveSpan(); + startBrowserTracingPageLoadSpan(client, spanContext); } else { - activeRootSpan = _customStartTransaction({ - name: initPathName, - op: 'pageload', - origin: 'auto.pageload.remix', - tags: DEFAULT_TAGS, - metadata: { - source: 'url', - }, - }); + _customStartTransaction(spanContext); } } function startNavigationSpan(matches: RouteMatch[]): void { + const spanContext: StartSpanOptions = { + name: matches[matches.length - 1].id, + op: 'navigation', + origin: 'auto.navigation.remix', + tags: DEFAULT_TAGS, + metadata: { + source: 'route', + }, + }; + // If _customStartTransaction is not defined, we know that we are using the browserTracingIntegration if (!_customStartTransaction) { const client = getClient(); @@ -118,27 +116,9 @@ function startNavigationSpan(matches: RouteMatch[]): void { return; } - startBrowserTracingNavigationSpan(client, { - name: matches[matches.length - 1].id, - op: 'navigation', - origin: 'auto.navigation.remix', - tags: DEFAULT_TAGS, - metadata: { - source: 'route', - }, - }); - - activeRootSpan = getActiveSpan(); + startBrowserTracingNavigationSpan(client, spanContext); } else { - activeRootSpan = _customStartTransaction({ - name: matches[matches.length - 1].id, - op: 'navigation', - origin: 'auto.navigation.remix', - tags: DEFAULT_TAGS, - metadata: { - source: 'route', - }, - }); + _customStartTransaction(spanContext); } } @@ -208,6 +188,7 @@ export function withSentry

, R extends React.Co _useEffect(() => { const activeRootSpan = getActiveSpan(); + if (activeRootSpan && matches && matches.length) { const transaction = getRootSpan(activeRootSpan); @@ -221,6 +202,8 @@ export function withSentry

, R extends React.Co }, []); _useEffect(() => { + const activeRootSpan = getActiveSpan(); + if (isBaseLocation) { if (activeRootSpan) { activeRootSpan.end(); From 695db9cb7d2f2f62c7b98b95622c73d0e7da1891 Mon Sep 17 00:00:00 2001 From: Onur Temizkan Date: Thu, 1 Feb 2024 12:10:43 +0000 Subject: [PATCH 5/8] Fix lint --- packages/remix/src/index.client.tsx | 1 + packages/remix/src/index.server.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/remix/src/index.client.tsx b/packages/remix/src/index.client.tsx index 3a56684c592f..3842e9a3701d 100644 --- a/packages/remix/src/index.client.tsx +++ b/packages/remix/src/index.client.tsx @@ -3,6 +3,7 @@ import { getCurrentScope, init as reactInit } from '@sentry/react'; import type { RemixOptions } from './utils/remixOptions'; export { captureRemixErrorBoundaryError } from './client/errors'; export { + // eslint-disable-next-line deprecation/deprecation remixRouterInstrumentation, withSentry, } from './client/performance'; diff --git a/packages/remix/src/index.server.ts b/packages/remix/src/index.server.ts index c0684a2c84e3..a34250100287 100644 --- a/packages/remix/src/index.server.ts +++ b/packages/remix/src/index.server.ts @@ -111,6 +111,7 @@ export * from '@sentry/node'; export { captureRemixServerException, wrapRemixHandleError } from './utils/instrumentServer'; export { ErrorBoundary, withErrorBoundary } from '@sentry/react'; +// eslint-disable-next-line deprecation/deprecation export { remixRouterInstrumentation, withSentry } from './client/performance'; export { captureRemixErrorBoundaryError } from './client/errors'; export { browserTracingIntegration } from './client/browserTracingIntegration'; From 6b2fb3005bd8fc34525d728ba7b757f3fababfb0 Mon Sep 17 00:00:00 2001 From: Onur Temizkan Date: Thu, 1 Feb 2024 12:10:55 +0000 Subject: [PATCH 6/8] Update CI workflow --- .github/workflows/build.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 999e290dcf50..42ebcf71a681 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -896,7 +896,7 @@ jobs: yarn test job_remix_integration_tests: - name: Remix v${{ matrix.remix }} (Node ${{ matrix.node }}) Tests + name: Remix v${{ matrix.remix }} (Node ${{ matrix.node }}) ${{ matrix.tracingIntegration && 'TracingIntegration'}} Tests needs: [job_get_metadata, job_build] if: needs.job_get_metadata.outputs.changed_remix == 'true' || github.event_name != 'pull_request' runs-on: ubuntu-20.04 @@ -906,13 +906,14 @@ jobs: matrix: node: [18, 20, 21] remix: [1, 2] - tracingIntegration: [false, true] # Remix v2 only supports Node 18+, so run Node 14, 16 tests separately include: - node: 14 remix: 1 - node: 16 remix: 1 + - tracingIntegration: true + remix: 2 steps: - name: Check out current commit (${{ needs.job_get_metadata.outputs.commit_label }}) uses: actions/checkout@v4 From 18683ec00819a265443a87874227362ebc02a441 Mon Sep 17 00:00:00 2001 From: Onur Temizkan Date: Fri, 2 Feb 2024 16:15:53 +0000 Subject: [PATCH 7/8] Address review comments. --- packages/remix/package.json | 2 +- packages/remix/src/client/performance.tsx | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/remix/package.json b/packages/remix/package.json index 8fdfc58b1afb..2133813e857a 100644 --- a/packages/remix/package.json +++ b/packages/remix/package.json @@ -75,7 +75,7 @@ "test:integration:v2": "export REMIX_VERSION=2 && run-s test:integration:v1", "test:integration:tracingIntegration": "export TRACING_INTEGRATION=true && run-s test:integration:v2", "test:integration:ci": "run-s test:integration:clean test:integration:prepare test:integration:client:ci test:integration:server", - "test:integration:prepare": "(cd test/integration && yarn install --force)", + "test:integration:prepare": "(cd test/integration && yarn install)", "test:integration:clean": "(cd test/integration && rimraf .cache node_modules build)", "test:integration:client": "yarn playwright install-deps && yarn playwright test test/integration/test/client/ --project='chromium'", "test:integration:client:ci": "yarn test:integration:client --reporter='line'", diff --git a/packages/remix/src/client/performance.tsx b/packages/remix/src/client/performance.tsx index 45bbef4f40c6..10e91837149d 100644 --- a/packages/remix/src/client/performance.tsx +++ b/packages/remix/src/client/performance.tsx @@ -52,7 +52,7 @@ let _useLocation: UseLocation | undefined; let _useMatches: UseMatches | undefined; let _customStartTransaction: ((context: TransactionContext) => Span | undefined) | undefined; -let _startTransactionOnLocationChange: boolean | undefined; +let _instrumentNavigation: boolean | undefined; function getInitPathName(): string | undefined { if (WINDOW && WINDOW.location) { @@ -140,7 +140,7 @@ export function remixRouterInstrumentation(useEffect: UseEffect, useLocation: Us useEffect, useLocation, useMatches, - startTransactionOnLocationChange, + instrumentNavigation: startTransactionOnLocationChange, customStartTransaction, }); @@ -212,7 +212,7 @@ export function withSentry

, R extends React.Co return; } - if (_startTransactionOnLocationChange && matches && matches.length) { + if (_instrumentNavigation && matches && matches.length) { if (activeRootSpan) { activeRootSpan.end(); } @@ -242,18 +242,18 @@ export function setGlobals({ useEffect, useLocation, useMatches, - startTransactionOnLocationChange, + instrumentNavigation, customStartTransaction, }: { useEffect?: UseEffect; useLocation?: UseLocation; useMatches?: UseMatches; - startTransactionOnLocationChange?: boolean; + instrumentNavigation?: boolean; customStartTransaction?: (context: TransactionContext) => Span | undefined; }): void { _useEffect = useEffect; _useLocation = useLocation; _useMatches = useMatches; - _startTransactionOnLocationChange = startTransactionOnLocationChange; + _instrumentNavigation = instrumentNavigation; _customStartTransaction = customStartTransaction; } From b028a6e58db227d768f03362e973722feac95250 Mon Sep 17 00:00:00 2001 From: Onur Temizkan Date: Fri, 2 Feb 2024 16:15:53 +0000 Subject: [PATCH 8/8] Address review comments. --- packages/remix/src/client/browserTracingIntegration.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/remix/src/client/browserTracingIntegration.ts b/packages/remix/src/client/browserTracingIntegration.ts index ef6e96bf1fb9..c0eb1a97148d 100644 --- a/packages/remix/src/client/browserTracingIntegration.ts +++ b/packages/remix/src/client/browserTracingIntegration.ts @@ -19,7 +19,7 @@ export function browserTracingIntegration(options: RemixBrowserTracingIntegratio useEffect: options.useEffect, useLocation: options.useLocation, useMatches: options.useMatches, - startTransactionOnLocationChange: options.instrumentNavigation, + instrumentNavigation: options.instrumentNavigation, }); const browserTracingIntegrationInstance = originalBrowserTracingIntegration({