Skip to content

Commit 742a5b0

Browse files
committed
Fix empty path to be more specific than a catch-all.
1 parent 82fbe32 commit 742a5b0

3 files changed

Lines changed: 103 additions & 3 deletions

File tree

packages/ra-router-tanstack/src/tanStackRouterProvider.spec.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import {
2626
PathlessLayoutRoutes,
2727
NestedResourcesPrecedence,
2828
PathlessLayoutRoutesPriority,
29+
PathlessLayoutRoutesWithEmptyRoute,
2930
} from './tanStackRouterProvider.stories';
3031
import { tanStackRouterProvider } from './tanStackRouterProvider';
3132

@@ -1506,6 +1507,22 @@ describe('tanStackRouterProvider', () => {
15061507
});
15071508
});
15081509

1510+
it('should match the empty path route as most specific within pathless layout routes', async () => {
1511+
window.location.hash = '#/posts';
1512+
1513+
render(<PathlessLayoutRoutesWithEmptyRoute />);
1514+
1515+
await waitFor(() => {
1516+
expect(screen.getByTestId('posts-page')).toBeInTheDocument();
1517+
});
1518+
1519+
fireEvent.click(screen.getByText('Home (path="")'));
1520+
1521+
await waitFor(() => {
1522+
expect(screen.getByTestId('home-page')).toBeInTheDocument();
1523+
});
1524+
});
1525+
15091526
describe('Resource Children (Route as children of Resource)', () => {
15101527
it('should navigate to child routes without matching parent edit route', async () => {
15111528
render(<NestedResourcesPrecedence />);

packages/ra-router-tanstack/src/tanStackRouterProvider.stories.tsx

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1482,6 +1482,89 @@ export const PathlessLayoutRoutes = () => {
14821482
);
14831483
};
14841484

1485+
export const PathlessLayoutRoutesWithEmptyRoute = () => {
1486+
const { RouterWrapper } = tanStackRouterProvider;
1487+
1488+
return (
1489+
<RouterProviderContext.Provider value={tanStackRouterProvider}>
1490+
<RouterWrapper>
1491+
<p style={{ marginBottom: 10 }}>
1492+
Expected: "/" renders Home Page (path=""). If you see
1493+
Catch-all Page instead, path="" is being treated as
1494+
catch-all.
1495+
</p>
1496+
<Routes>
1497+
<Route
1498+
path="*"
1499+
element={
1500+
<div data-testid="catchall-page">
1501+
Catch-all Page
1502+
</div>
1503+
}
1504+
/>
1505+
<Route
1506+
element={
1507+
<div data-testid="layout-wrapper">
1508+
<h2>Layout Wrapper</h2>
1509+
<nav>
1510+
<LinkBase
1511+
to="/posts"
1512+
style={{ marginRight: 10 }}
1513+
>
1514+
Posts
1515+
</LinkBase>
1516+
<LinkBase to="/comments">Comments</LinkBase>
1517+
</nav>
1518+
<nav>
1519+
<LinkBase
1520+
to="/"
1521+
style={{ marginRight: 10 }}
1522+
>
1523+
Home (path="")
1524+
</LinkBase>
1525+
</nav>
1526+
<div
1527+
style={{
1528+
border: '2px solid blue',
1529+
padding: 20,
1530+
marginTop: 10,
1531+
}}
1532+
>
1533+
<RouterOutlet />
1534+
</div>
1535+
</div>
1536+
}
1537+
>
1538+
<Route
1539+
path=""
1540+
element={
1541+
<div data-testid="home-page">
1542+
Home Page (path="")
1543+
</div>
1544+
}
1545+
/>
1546+
<Route
1547+
path="/posts"
1548+
element={
1549+
<div data-testid="posts-page">Posts Page</div>
1550+
}
1551+
/>
1552+
<Route
1553+
path="/comments"
1554+
element={
1555+
<div data-testid="comments-page">
1556+
Comments Page
1557+
</div>
1558+
}
1559+
/>
1560+
</Route>
1561+
</Routes>
1562+
<LocationDisplay />
1563+
</RouterWrapper>
1564+
</RouterProviderContext.Provider>
1565+
);
1566+
};
1567+
14851568
export const PathlessLayoutRoutesPriority = () => {
14861569
const { RouterWrapper } = tanStackRouterProvider;
14871570

packages/ra-router-tanstack/src/tanStackRouterProvider.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -744,8 +744,8 @@ const Routes = ({ children, location: locationProp }: RouterRoutesProps) => {
744744
childMatch &&
745745
// If no best match yet, or the child route is more specific than the current best, use this one
746746
(!bestMatch ||
747-
(bestMatch.route.path &&
748-
childMatch.route.path &&
747+
(bestMatch.route.path !== undefined &&
748+
childMatch.route.path !== undefined &&
749749
isMoreSpecific(
750750
bestMatch.route.path,
751751
childMatch.route.path
@@ -782,7 +782,7 @@ const Routes = ({ children, location: locationProp }: RouterRoutesProps) => {
782782
// If no best match yet, or this route is more specific than the current best, use this one
783783
if (
784784
!bestMatch ||
785-
(bestMatch.route.path &&
785+
(bestMatch.route.path !== undefined &&
786786
isMoreSpecific(
787787
bestMatch.route.path,
788788
route.path

0 commit comments

Comments
 (0)