ITADN

[🐞] routeLoader$({ search: [] }) drops route params when the request has a query string

#8964Opentidiview 创建于 4 天前
T
tidiviewcommented
### Which component is affected? Qwik Router ### Describe the bug On a dynamic route (e.g. `/[lang]/index.tsx`), a `routeLoader$` declared with the `{ search: [] }` option receives an **empty `params` object** as soon as the request URL carries any query string — even though the exact same request without a query string resolves `params` correctly. This isn't just a 404/routing bug — it's `params` silently getting lost. Any application code that reads `params.xxx` inside such a loader gets `undefined`/empty values whenever a visitor's URL has a query parameter (tracking params, search, a redirect token, etc.), with no error raised. In our real app it does surface as a hard 404, only because our loader explicitly validates the param and rejects the request when it's missing — but the root cause is the lost `params`, not routing itself. Also observed inside the loader (via a temporary `console.error`): with the query string present, the loader's own `url.href` has *also* dropped the query string entirely — it reads back as the bare path. This is consistent with `search: []`'s documented behavior of filtering the URL handed to the loader (per the `LoaderOptions.search` doc comment), except it appears to also lose the route's own path params in the process. We found this while migrating a production app from beta.38 to beta.40 (Vite 8/Rolldown). **It reproduces identically on beta.39 with Vite 7**, so it predates that migration and is unrelated to the Vite 8/Rolldown switch — just flagging that clearly since beta.40 was announced right before we hit this. ### Isolating the cause Confirmed on a clean 2-file repro (`npm create qwik@beta`, nothing from our real app): - Removing the `{ search: [] }` option from the loader makes the bug disappear — `params.lang` stays correct regardless of the query string. Everything else in the file is unchanged. - The starter's root route `/` (no dynamic segment, no `search` option) is never affected, with or without a query string. - `strictLoaders` (the `qwikRouter()` plugin option) does **not** matter — reproduced identically with the default (`true`) and with `strictLoaders: false`. ### Reproduction https://github.com/tidiview/qwik-router-query-404-repro ### Steps to reproduce 1. `npm install` 2. `npm run dev` 3. In another terminal: ``` curl -s http://localhost:5173/fr/ # → "lang param = \"fr\"" (correct) curl -s http://localhost:5173/fr/?foo=bar # → "lang param = null" (BUG: params lost) ``` Also reproduces the same way under `npm run build` + a Cloudflare Pages adapter build served via `wrangler pages dev` (production build, not just dev SSR). ### System Info ```shell System: OS: Windows 10 10.0.19045 Binaries: Node: 24.7.0 npm: 11.5.1 npmPackages: @qwik.dev/core: ^2.0.0-beta.40 => 2.0.0-beta.40 @qwik.dev/router: ^2.0.0-beta.40 => 2.0.0-beta.40 typescript: 5.9.3 => 5.9.3 vite: 8.2.1 => 8.2.1 ``` Also reproduced with `@qwik.dev/core`/`@qwik.dev/router` `2.0.0-beta.39` and `vite@7.3.2`. ### Additional Information Happy to add more detail or test a fix against our real app — this is currently blocking us from moving past beta.38 in production, since our `/[lang]/` route uses `search: []` on its loader and validates `params.lang`, so every request to that page carrying a query string (our edit flow's POST/redirect/GET pattern uses one) gets a hard 404.
0 条评论