Skip to content

Fix the most specific matching route when using pathless routes#11138

Merged
djhi merged 4 commits intomasterfrom
fix-most-specific-matching-route
Jan 29, 2026
Merged

Fix the most specific matching route when using pathless routes#11138
djhi merged 4 commits intomasterfrom
fix-most-specific-matching-route

Conversation

@Madeorsk
Copy link
Copy Markdown
Contributor

@Madeorsk Madeorsk commented Jan 26, 2026

Problem

In #11102, @WiXSL pointed the following (#11102 (comment)):

Pathless layout routes short‑circuit the match loop on the first layout with matching children. This bypasses the later “more specific” logic and can make matching order‑dependent, potentially selecting a layout route even if a more specific sibling should win.

After more investigations, he was right. When a more specific route was defined after a catch-all route nested in a pathless route, the catch-all route was returned before the more specific route was even evaluated. In the following example, the catch-all route /users/* was matched when the pathname was /users/jane_doe/block.

<Route element={<RouterOutlet />}>
    <Route
        path="/users/*"
        element={
            <div data-testid="users-page">
                Users View
            </div>
        }
    />
</Route>
<Route
    path="/users/:username/block"
    element={
        <div data-testid="block-user-page">
            Block a user
        </div>
    }
/>

Solution

Extract the matching route finding algorithm in a function, and call it recursively with the children of the pathless route to always find the most specific route.

How To Test

Additional Checks

  • The PR targets master for a bugfix or a documentation fix, or next for a feature
  • The PR includes unit tests (if not possible, describe why)
  • The PR includes one or several stories (if not possible, describe why)
  • The documentation is up to date

Comment on lines +1499 to +1510
<LinkBase
to="/users/john_doe"
style={{ marginRight: 10 }}
>
User
</LinkBase>
<LinkBase
to="/users/jane_doe/block"
style={{ marginRight: 10 }}
>
Block a user
</LinkBase>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't these two routes share the same root? i.e. either john_doe or jane_doe? Otherwise I don't see the point of the test.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't actually matter. What we're testing here is that /users/:username/block route is working as expected (meaning it should show the "Block a user" and not the catch-all "Users View"). The shared root of the two routes is /users and that's enough. But I can use john_doe in the two links if you think it's more logical.

Comment thread packages/ra-router-tanstack/src/tanStackRouterProvider.tsx
Comment thread packages/ra-router-tanstack/src/tanStackRouterProvider.tsx
@djhi djhi added this to the 5.14.1 milestone Jan 29, 2026
@djhi djhi merged commit 99d2b5b into master Jan 29, 2026
15 checks passed
@djhi djhi deleted the fix-most-specific-matching-route branch January 29, 2026 10:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

RFR Ready For Review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants