From 5f64ec20559d7c7b1be5a03445a43c790a5c67dc Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Mon, 17 Oct 2022 12:35:40 +0200 Subject: [PATCH] fix(react): Support root and wildcard routes in react router v6 --- packages/react/src/reactrouterv6.tsx | 14 ++-- packages/react/test/reactrouterv6.test.tsx | 92 ++++++++++++++++++++++ 2 files changed, 101 insertions(+), 5 deletions(-) diff --git a/packages/react/src/reactrouterv6.tsx b/packages/react/src/reactrouterv6.tsx index ebffcbeea83a..66282545f248 100644 --- a/packages/react/src/reactrouterv6.tsx +++ b/packages/react/src/reactrouterv6.tsx @@ -122,13 +122,17 @@ function getNormalizedName( const path = route.path; if (path) { - const newPath = path[0] === '/' ? path : `/${path}`; + const newPath = path[0] === '/' || pathBuilder[pathBuilder.length - 1] === '/' ? path : `/${path}`; pathBuilder += newPath; if (branch.pathname === location.pathname) { - // If the route defined on the element is something like - // Product} /> - // We should check against the branch.pathname for the number of / seperators - if (getNumberOfUrlSegments(pathBuilder) !== getNumberOfUrlSegments(branch.pathname)) { + if ( + // If the route defined on the element is something like + // Product} /> + // We should check against the branch.pathname for the number of / seperators + getNumberOfUrlSegments(pathBuilder) !== getNumberOfUrlSegments(branch.pathname) && + // We should not count wildcard operators in the url segments calculation + pathBuilder.slice(-2) !== '/*' + ) { return [newPath, 'route']; } return [pathBuilder, 'route']; diff --git a/packages/react/test/reactrouterv6.test.tsx b/packages/react/test/reactrouterv6.test.tsx index f5733b9847f1..6d0faa719f57 100644 --- a/packages/react/test/reactrouterv6.test.tsx +++ b/packages/react/test/reactrouterv6.test.tsx @@ -6,6 +6,7 @@ import { matchRoutes, MemoryRouter, Navigate, + Outlet, Route, Routes, useLocation, @@ -525,5 +526,96 @@ describe('React Router v6', () => { metadata: { source: 'route' }, }); }); + + it('does not add double slashes to URLS', () => { + const [mockStartTransaction, { mockSetName }] = createInstrumentation(); + const wrappedUseRoutes = wrapUseRoutes(useRoutes); + + const Routes = () => + wrappedUseRoutes([ + { + path: '/', + element: ( +
+ +
+ ), + children: [ + { + path: 'tests', + children: [ + { index: true, element:
Main Test
}, + { path: ':testId/*', element:
Test Component
}, + ], + }, + { path: '/', element: }, + { path: '*', element: }, + ], + }, + { + path: '/', + element:
, + children: [ + { path: '404', element:
Error
}, + { path: '*', element: }, + ], + }, + ]); + + render( + + + , + ); + + expect(mockStartTransaction).toHaveBeenCalledTimes(1); + // should be /tests not //tests + expect(mockSetName).toHaveBeenLastCalledWith('/tests', 'route'); + }); + + it('handles wildcard routes properly', () => { + const [mockStartTransaction, { mockSetName }] = createInstrumentation(); + const wrappedUseRoutes = wrapUseRoutes(useRoutes); + + const Routes = () => + wrappedUseRoutes([ + { + path: '/', + element: ( +
+ +
+ ), + children: [ + { + path: 'tests', + children: [ + { index: true, element:
Main Test
}, + { path: ':testId/*', element:
Test Component
}, + ], + }, + { path: '/', element: }, + { path: '*', element: }, + ], + }, + { + path: '/', + element:
, + children: [ + { path: '404', element:
Error
}, + { path: '*', element: }, + ], + }, + ]); + + render( + + + , + ); + + expect(mockStartTransaction).toHaveBeenCalledTimes(1); + expect(mockSetName).toHaveBeenLastCalledWith('/tests/:testId/*', 'route'); + }); }); });