parseLocation keeps the raw publicHref when rewrite is set, so a non-canonical search string re-runs every loader after hydration
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 15.1k
- Forks
- 1.9k
- Avg merge
- 1d 20h
- Merged PRs (30d)
- 143
Description
Which project does this relate to?
Router
Describe the bug
When any rewrite is configured on the router — even a no-op one — landing on a URL whose search string is not in the router's canonical form (for example ?q=a%2Ab instead of ?q=a*b, ?q=two%20words, ?a=1&&b=2) runs all matched loaders a second time right after hydration.
Nothing visible happens: the address bar does not change and no navigation occurs, so this is easy to miss. In our app every paid-ad landing (ad networks tend to encode *, spaces, etc. differently than stringifySearch) made an extra server-function call on the client after SSR had already run the loader.
Without rewrite, the same URL runs the loader exactly once.
Complete minimal reproducer
https://github.com/martin-ragan/tanstack-rewrite-publichref-repro
Steps to Reproduce the Bug
In the PR description
Expected behavior
The same number of loader runs with or without rewrite. The rewrite branch of parseLocation should produce a publicHref with the canonical search string, the way the no-rewrite branch does — e.g. by running the canonicalised url back through executeRewriteOutput, or by replacing only the search part of href with searchStr. Transitioner and buildLocation would then agree on landing and no redundant commitLocation → load() would fire.
Screenshots or Videos
No response
Platform
OS: macOS
Browser: Chromium (Playwright 1.63.0), also happy-dom for the unit test
Runtime: bun 1.3.6, Vite 8.3.
Additional context
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the rewrite branch of parseLocation and compare it with the no-rewrite branch, especially executeRewriteOutput and searchStr handling. Reproduce the issue with the linked minimal repository or the happy-dom unit test using encoded search strings and a no-op rewrite. Done means publicHref contains the canonical search string and hydration runs matched loaders only once.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend, web-dev
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100