#8448·router

parseLocation keeps the raw publicHref when rewrite is set, so a non-canonical search string re-runs every loader after hydration

Author: martin-raganCreated Sep 16, 2026Updated Sep 16, 2026

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