Problem
While testing the blog, query params sometimes appeared NOT to carry forward to the navigated page. The client router needs explicit, locked test coverage for query-string handling across every navigation path, so a genuine drop is caught and the spec-correct cases are documented.
Investigation of packages/core/src/router-client.js shows MOST paths are correct:
finalUrl defaults to the full link href (which includes the query string) and drives pushState (lines ~1626, ~1692, ~1701), so a link with a query string keeps it in the URL.
- The snapshot and prefetch caches key on
pathname + search (cacheKey line ~817; prefetch key line ~316), so ?x=1 and ?x=2 are distinct entries.
One path deliberately drops pre-existing params, and it is spec-compliant, not a bug: the GET-form submission resets url.search = '' and rebuilds it from the form body (line ~957), matching the native HTML5 GET-form algorithm (the form fields replace the action's query). The tests must assert this so it is not later "fixed" into a regression.
So this is primarily a test-coverage task that will ALSO surface any genuine drop (a real bug to fix).
Design / approach
Add a browser test that exercises every nav path and asserts location.search (and the pushState URL) after a real soft swap. Model it on the existing packages/core/test/routing/browser/*.test.js files, which mock window.fetch and call navigate() / drive clicks.
Implementation notes (for the implementing agent)
- Where: new
packages/core/test/routing/browser/query-params.test.js. Import { enableClientRouter, navigate } from ../../../src/router-client.js; mock window.fetch to return a <!--wj:children--> body (see nav-scroll-instant.test.js for the exact harness shape).
- Key code paths in
packages/core/src/router-client.js: click handler href = anchor.href (~L350), finalUrl (~L1626/1692), pushState(finalUrl) (~L1701), cacheKey = pathname + search (~L815-817), prefetch key (~L316), GET-form url.search = '' (~L957).
- Landmines: (a) the GET-form replacement is correct, do NOT call it a bug; (b) a server
redirect() legitimately changes finalUrl to the redirect target (params may differ by design); (c) linkedom (the unit DOM) does not do real navigation, so the headline assertions belong in the browser layer, not a unit test.
- Invariants: no
.ts in packages/ (plain JS + JSDoc).
- Tests + docs: browser test is the headline; if a genuine drop is found and fixed, note the corrected behavior in
agent-docs/advanced.md (client router section).
Acceptance criteria
Problem
While testing the blog, query params sometimes appeared NOT to carry forward to the navigated page. The client router needs explicit, locked test coverage for query-string handling across every navigation path, so a genuine drop is caught and the spec-correct cases are documented.
Investigation of
packages/core/src/router-client.jsshows MOST paths are correct:finalUrldefaults to the full linkhref(which includes the query string) and drivespushState(lines ~1626, ~1692, ~1701), so a link with a query string keeps it in the URL.pathname + search(cacheKeyline ~817; prefetch key line ~316), so?x=1and?x=2are distinct entries.One path deliberately drops pre-existing params, and it is spec-compliant, not a bug: the GET-form submission resets
url.search = ''and rebuilds it from the form body (line ~957), matching the native HTML5 GET-form algorithm (the form fields replace the action's query). The tests must assert this so it is not later "fixed" into a regression.So this is primarily a test-coverage task that will ALSO surface any genuine drop (a real bug to fix).
Design / approach
Add a browser test that exercises every nav path and asserts
location.search(and thepushStateURL) after a real soft swap. Model it on the existingpackages/core/test/routing/browser/*.test.jsfiles, which mockwindow.fetchand callnavigate()/ drive clicks.Implementation notes (for the implementing agent)
packages/core/test/routing/browser/query-params.test.js. Import{ enableClientRouter, navigate }from../../../src/router-client.js; mockwindow.fetchto return a<!--wj:children-->body (seenav-scroll-instant.test.jsfor the exact harness shape).packages/core/src/router-client.js: click handlerhref = anchor.href(~L350),finalUrl(~L1626/1692),pushState(finalUrl)(~L1701),cacheKey=pathname + search(~L815-817), prefetch key (~L316), GET-formurl.search = ''(~L957).redirect()legitimately changesfinalUrlto the redirect target (params may differ by design); (c)linkedom(the unit DOM) does not do real navigation, so the headline assertions belong in the browser layer, not a unit test..tsinpackages/(plain JS + JSDoc).agent-docs/advanced.md(client router section).Acceptance criteria
location.searchafter the soft swap AND in thepushStateURL/a?x=1then/b?y=2lands withsearch === '?y=2'(not merged, not dropped)finalUrlto the redirect target's searchrouter-client.js;agent-docs/advanced.mdupdated if behavior changed