Updating search params via a <Link> does not work on the first click if a declarative route mask is used
Describe the bug
When using a <Link> component, I expect that using the search prop would update the search parameters in the URL whenever I click the <Link>.
For example, the code snippet below should increment the page search param in the URL whenever clicked.
<Link search={(prev) => ({ ...prev, page: (prev.page ?? 1) + 1 })}>Click me<Link />
This works great.
However, when I add a route mask to the router, the search parameters no longer update on the first click.
const maskSearchUserId = createRouteMask({
routeTree,
search: (prevSearch) => {
const newSearch = { ...prevSearch };
delete newSearch.userId;
return newSearch;
},
});
// Create a new router instance
const router = createRouter({
routeTree,
routeMasks: [maskSearchUserId],
});
For reference, here is the search param setup:
import { Link, createRootRoute } from '@tanstack/react-router';
import z from 'zod';
const searchSchema = z.object({
userId: z.coerce.string().min(1).optional().catch(undefined),
page: z.coerce.number().min(1).catch(1),
});
export const Route = createRootRoute({
validateSearch: searchSchema,
...
});
Your Example Website or App
https://stackblitz.com/edit/github-rbjvhp?file=src%2Froutes%2F__root.tsx
Steps to Reproduce the Bug or Issue
- Go to the StackBlitz link provided
- Open the StackBlitz preview in a new tab via the "Open Preview in new tab" button so you can view the URL as it updates
- Click once on the "Click to increment page search param" link and observe the URL does not change.
- Click a second time on the "Click to increment page search param" link and observe the URL search params do change from
?page=1to?page=2.
Expected behaviour
As a user, I expected the URL search params to update whenever I clicked on a <Link> that updates the search parameters.
Screenshots or Videos
Here's a demo where I click on the <Link> twice, a few seconds apart.
Notice how the URL only updates the second time.
https://github.com/user-attachments/assets/671b5fe3-d8a7-4970-9022-4902f32cc784
Platform
- OS: macOS
- Browser: Chrome
- Version 127.0.6533.89 (Official Build) (arm64)
Additional context
- Removing the route mask resolves the issue.
- Supplying a "dummy" route mask (below) that passes the previous value through does not resolve the issue.
search: (prev) => {
return prev;
},