Under the TanStack build, three navigation producers embedded the query
string inside the router's `to` (`navigate({ to: '/path?s=...' })`): the
custom nuqs adapter's updateUrl, the next/router compat shim's
push/replace, and the next/navigation compat shim's push/replace.
TanStack router-core treats the whole `to` string as a path —
buildLocation → interpolatePath → decodePath percent-DECODES it, then
sanitizePathSegment strips control characters (/[\x00-\x1f\x7f]/). Every
%0A newline in a query value was silently deleted.
User-visible symptom: Logs Explorer SQL (the `s` param) lost its
newlines on Run/reload, gluing `order by timestamp desc` and `limit 5`
into `order by timestamp desclimit 5`, which then failed the LIMIT lint.
Any query value with control characters was affected on client-side
navigations. The Next build was unaffected.
Fix: never embed `?query`/`#hash` in `to`.
- Hoist the next/link shim's splitInternalUrl into lib/internal-url.ts
(shared; behavior unchanged for Link) and use it in the next/router
and next/navigation shims to pass { to, search, hash } separately —
`search: {}` / `hash: ''` keep Next's push-without-query semantics.
Prefetch/preloadRoute paths are split the same way so they preload
the real target.
- The nuqs adapter now navigates with `to` = current pathname and the
full search state as a record (buildSearchUpdateArgs, replacing
buildSearchUpdateTarget), letting the app's Next-style search codec
serialize values losslessly. Side effect: nuqs-written URLs now
percent-encode reserved chars like `:` (URLSearchParams semantics),
consistent with every other producer; values round-trip identically.
- Also fix the pre-existing tsc error on the navigate pipeline
(`useParams({ strict: false })` can type as undefined).
Tests: lib/router-url-shape.test.tsx now drives a real router through
both producer shapes with multi-line SQL fixtures asserting lossless
round-trips ("limit 5" intact); splitInternalUrl tests moved to
lib/internal-url.test.ts with %0A and already-basepath-relative cases;
nuqs adapter tests updated for buildSearchUpdateArgs.
Claude-Session: https://claude.ai/code/session_01MLH8WVg8zBJnmZTYTV3ooo