diff --git a/packages/react/src/reactrouterv6.tsx b/packages/react/src/reactrouterv6.tsx index bd127ca1010a..792d36385566 100644 --- a/packages/react/src/reactrouterv6.tsx +++ b/packages/react/src/reactrouterv6.tsx @@ -78,6 +78,7 @@ function getNormalizedName( routes: RouteObject[], location: Location, branches: RouteMatch[], + basename: string = '', ): [string, TransactionSource] { if (!routes || routes.length === 0) { return [location.pathname, 'url']; @@ -99,7 +100,8 @@ function getNormalizedName( if (path) { const newPath = path[0] === '/' || pathBuilder[pathBuilder.length - 1] === '/' ? path : `/${path}`; pathBuilder += newPath; - if (branch.pathname === location.pathname) { + + if (basename + branch.pathname === location.pathname) { if ( // If the route defined on the element is something like // Product} /> @@ -108,9 +110,9 @@ function getNormalizedName( // We should not count wildcard operators in the url segments calculation pathBuilder.slice(-2) !== '/*' ) { - return [newPath, 'route']; + return [basename + newPath, 'route']; } - return [pathBuilder, 'route']; + return [basename + pathBuilder, 'route']; } } } @@ -131,7 +133,7 @@ function updatePageloadTransaction( : (_matchRoutes(routes, location, basename) as unknown as RouteMatch[]); if (activeTransaction && branches) { - activeTransaction.setName(...getNormalizedName(routes, location, branches)); + activeTransaction.setName(...getNormalizedName(routes, location, branches, basename)); } } @@ -149,7 +151,7 @@ function handleNavigation( activeTransaction.finish(); } - const [name, source] = getNormalizedName(routes, location, branches); + const [name, source] = getNormalizedName(routes, location, branches, basename); activeTransaction = _customStartTransaction({ name, op: 'navigation', diff --git a/packages/react/test/reactrouterv6.4.test.tsx b/packages/react/test/reactrouterv6.4.test.tsx index 19a714f853a3..a5c35169c283 100644 --- a/packages/react/test/reactrouterv6.4.test.tsx +++ b/packages/react/test/reactrouterv6.4.test.tsx @@ -307,7 +307,51 @@ describe('React Router v6.4', () => { op: 'navigation', origin: 'auto.navigation.react.reactrouterv6', tags: { 'routing.instrumentation': 'react-router-v6' }, - metadata: { source: 'url' }, + metadata: { source: 'route' }, + }); + }); + + it('works with parameterized paths and `basename`', () => { + const [mockStartTransaction] = createInstrumentation(); + const sentryCreateBrowserRouter = wrapCreateBrowserRouter(createMemoryRouter as CreateRouterFunction); + + const router = sentryCreateBrowserRouter( + [ + { + path: '/', + element: , + }, + { + path: ':orgId', + children: [ + { + path: 'users', + children: [ + { + path: ':userId', + element:
User
, + }, + ], + }, + ], + }, + ], + { + initialEntries: ['/admin'], + basename: '/admin', + }, + ); + + // @ts-expect-error router is fine + render(); + + expect(mockStartTransaction).toHaveBeenCalledTimes(2); + expect(mockStartTransaction).toHaveBeenLastCalledWith({ + name: '/admin/:orgId/users/:userId', + op: 'navigation', + origin: 'auto.navigation.react.reactrouterv6', + tags: { 'routing.instrumentation': 'react-router-v6' }, + metadata: { source: 'route' }, }); }); });