router: visible `<Link>` prefetch skips bundles for dynamic and catch-all routes
Maintainers usually reply within 1 day
@maiieul is already working on this.
Since Sep 29, 2026.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 55/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- typescript
- Domain
- frontend, performance, web-dev
Research direction
Trace link-prefetch.ts from preloadRouteBundles through get-route-imports.ts, then compare it with prefetchRoute, normalizePathname, and ensureSlash. Reproduce the issue with the qwikrouter-test.prod e2e app using dynamic, catch-all, and static routes. Done means visible links preload the expected route module and component bundles without unnecessarily importing layouts and pages.
Written by the indexing model from the issue text.
Description
What is it?
- Bug
Description
A visible <Link> (prefetchBundles="visible", the default) preloads nothing for dynamic routes. link-prefetch.ts calls preloadRouteBundles(url.pathname), so the preloader gets products/123/, but the bundle graph keys routes by name (products/[id]/, see get-route-imports.ts). Static routes work because their pathname is their route name. Link clicks and SPA navigation go through prefetchRoute(), which resolves the route name first. 48fb84ed0 had moved the visible path to prefetchRoute() too, but the merge with the shared-observer refactor (4ba1ad594) only carried over the data branch.
Catch-all routes miss even through prefetchRoute(). The build keys docs/[...slug]/index.tsx as docs/[...slug] with no trailing slash, because normalizePathname treats a last segment containing . as a file name. prefetchRoute() calls ensureSlash and looks up docs/[...slug]/, so Link clicks and SPA navigation miss catch-all bundles too. Other routes whose last segment contains a dot, and maybe every route with trailingSlash: false, likely hit the same mismatch (not checked).
Reproduced on a production build of the qwikrouter-test.prod e2e app with temporary [id], [...slug] and static routes: only the static link's bundles loaded. #9040 (closed, untested) switched the observer to prefetchRoute(). With it, [id] links loaded their route module and component bundle, but [...slug] links only got their route module. prefetchRoute() also runs loadRoute(), which imports each visible link's layout and page modules instead of only queuing preload hints, so pages with many links would do more work.
- Dominant language
- TypeScript
- Stars
- 22.1k
- Forks
- 1.4k
- Avg merge
- 1d 17h
- Merged PRs (30d)
- 98
Getting set up
Starts the project's dev container in your browser, under your own GitHub account.
- Ships a Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing 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.
More from QwikDev/qwik
-
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
Maintainers usually reply within 1 day
-
docs router V2
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Maintainers usually reply within 1 day
-
DX enhancement V2
Difficulty 2/5 1-3 hours Newbie friendliness 64/100
QwikDev/qwik#8480 · 2 comments ·
Maintainers usually reply within 1 day
-
[🐞] Production build hoists a nested `.map()` handler's captures out of both loops, so SSR failsOpen
Difficulty 4/5 3-5 days Newbie friendliness 25/100
QwikDev/qwik#9190 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 22/100
Maintainers usually reply within 1 day
Similar issues
-
[Bug]: Server git tests sign fixture commits with the developer's key when run from the repo rootOpen
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
melgarafael/DeskcommCRM#2657 ·
Maintainers usually reply within 1 day
-
Difficulty 1/5 Under an hour Newbie friendliness 85/100
MystenLabs/MemWal#1163 · 2 comments ·
Maintainers usually reply within 1 day
-
Mondriaan
Difficulty 1/5 Under an hour Newbie friendliness 88/100
knaw-huc/textannoviz#709 ·
Maintainers usually reply within 1 day
-
billion-context-pi
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
ranxianglei/billion-context#2521 · 3 comments ·
Maintainers usually reply within 1 day