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
fix(react): Fix React Router v6 paramaterization #5515
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -20,9 +20,23 @@ type Params<Key extends string = string> = { | |||||||||||||||||
readonly [key in Key]: string | undefined; | ||||||||||||||||||
}; | ||||||||||||||||||
|
||||||||||||||||||
// https://github.com/remix-run/react-router/blob/9fa54d643134cd75a0335581a75db8100ed42828/packages/react-router/lib/router.ts#L114-L134 | ||||||||||||||||||
interface RouteMatch<ParamKey extends string = string> { | ||||||||||||||||||
/** | ||||||||||||||||||
* The names and values of dynamic parameters in the URL. | ||||||||||||||||||
*/ | ||||||||||||||||||
params: Params<ParamKey>; | ||||||||||||||||||
/** | ||||||||||||||||||
* The portion of the URL pathname that was matched. | ||||||||||||||||||
*/ | ||||||||||||||||||
pathname: string; | ||||||||||||||||||
/** | ||||||||||||||||||
* The portion of the URL pathname that was matched before child routes. | ||||||||||||||||||
*/ | ||||||||||||||||||
pathnameBase: string; | ||||||||||||||||||
/** | ||||||||||||||||||
* The route object that was used to match. | ||||||||||||||||||
*/ | ||||||||||||||||||
route: RouteObject; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
|
@@ -94,13 +108,31 @@ function getNormalizedName( | |||||||||||||||||
|
||||||||||||||||||
const branches = matchRoutes(routes, location); | ||||||||||||||||||
|
||||||||||||||||||
let pathBuilder = ''; | ||||||||||||||||||
if (branches) { | ||||||||||||||||||
// eslint-disable-next-line @typescript-eslint/prefer-for-of | ||||||||||||||||||
for (let x = 0; x < branches.length; x++) { | ||||||||||||||||||
if (branches[x].route && branches[x].route.path && branches[x].pathname === location.pathname) { | ||||||||||||||||||
const path = branches[x].route.path; | ||||||||||||||||||
const branch = branches[x]; | ||||||||||||||||||
const route = branch.route; | ||||||||||||||||||
if (route) { | ||||||||||||||||||
// Early return if index route | ||||||||||||||||||
if (route.index) { | ||||||||||||||||||
return [branch.pathname, 'route']; | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
const path = route.path; | ||||||||||||||||||
if (path) { | ||||||||||||||||||
return [path, 'route']; | ||||||||||||||||||
const newPath = path[0] === '/' ? path : `/${path}`; | ||||||||||||||||||
pathBuilder += newPath; | ||||||||||||||||||
if (branch.pathname === location.pathname) { | ||||||||||||||||||
// If the route defined on the element is something like | ||||||||||||||||||
// <Route path="/stores/:storeId/products/:productId" element={<div>Product</div>} /> | ||||||||||||||||||
// We should check against the branch.pathname for the number of / seperators | ||||||||||||||||||
if (pathBuilder.split('/').length !== branch.pathname.split('/').length) { | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this a safe check? Just asking because I used URL segment counting in my Express router instrumentation and I had to handle a few edge cases. For example, could there be problems with routes starting or ending with a Just a suggestion but now that I'm thinking about it, we could extract this function sentry-javascript/packages/tracing/src/integrations/node/express.ts Lines 387 to 394 in 6ea53ed
to our utils package and use it here. But totally optional ofc. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great point! I'm going to extract out |
||||||||||||||||||
return [newPath, 'route']; | ||||||||||||||||||
} | ||||||||||||||||||
return [pathBuilder, 'route']; | ||||||||||||||||||
} | ||||||||||||||||||
} | ||||||||||||||||||
} | ||||||||||||||||||
} | ||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just out of curiosity: why the index for loop?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's to stay consistent with RR5 integration. Not sure if there's any specific reason there though.
sentry-javascript/packages/react/src/reactrouter.tsx
Lines 79 to 84 in 9b7131f
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll just keep the explicit for loop, though technically it is extra bytes