feat(qwik-router): exclude prerendered routes from the server route plan#8742
Conversation
🦋 Changeset detectedLatest commit: cf7776a The changes in this PR will be included in the next version bump. This PR includes changesets to release 5 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
This would be better implemented by detecting routes with non-GET server entry points; then you could have just |
2509236 to
1a3e51e
Compare
ee995fa to
25cae84
Compare
wmertens
left a comment
There was a problem hiding this comment.
I think the concept is great, but I think it's SSR that should be special-cased (?ssr) for the routerconfig because both the client and SSG need the full trie, no?
Furthermore, a filtered trie should also remove all intermediate nodes that no longer have a leaf, I'm not sure that's happening, can you add a test?
add0a75 to
c8f37f7
Compare
@qwik.dev/core
@qwik.dev/router
eslint-plugin-qwik
create-qwik
@qwik.dev/optimizer
commit: |
Add an opt-in `serverExcludeRoutes` option (glob patterns, same syntax as the SSG adapter's `ssg.include`). Matching static page routes are omitted from the runtime server route plan, so their components tree-shake out of the deployed server bundle. This keeps size-capped edge runtimes (e.g. Cloudflare Workers) from growing with prerendered page count. SSG still prerenders the routes and the client/SPA build is unaffected. The SSG build entry imports a new `@qwik-router-config?ssg` variant that always carries the full route plan; dev and the client build keep every route as well. Exclusion applies to the production server build only. Restricted to static (non-dynamic) routes with no server action$ or per-request SSR fallback; the user certifies a listed route is fully static.
c8f37f7 to
cf7776a
Compare
built with Refined Cloudflare Pages Action⚡ Cloudflare Pages Deployment
|

What is it?
Description
Add an opt-in
serverExcludeRoutesoption (glob patterns, same syntax as the SSG adapter'sssg.include). Matching static page routes are omitted from the runtime server route plan, so their components tree-shake out of the deployed server bundle. This keeps size-capped edge runtimes (e.g. Cloudflare Workers) from growing with prerendered page count.SSG still prerenders the routes and the client/SPA build is unaffected. The SSG build entry imports a new
@qwik-router-config?ssgvariant that always carries the full route plan; dev and the client build keep every route as well. Exclusion applies to the production server build only.Restricted to static (non-dynamic) routes with no server
action$or per-request SSR fallback; the user certifies a listed route is fully static.How it works
createRouteTester(the same matcher SSG uses), so the glob syntax is identical tossg.include.createRoutes, a matched static route's loader is skipped, so its trie node prunes and the route's chunk tree-shakesout.
routeIdMapmembership stays the single source of truth (the_Rloader-hash emission now mirrors it).@qwik-router-config?ssgvirtual-module variant carries the full plan for the SSG build entry; the default config(runtime server) gets the filtered plan. Dev and the client build also use the full plan, so local dev and SPA navigation are unaffected.
Why opt-in and static-only
At codegen time the build has no route-handler info (no
action$/onRequestdetection, loaders aren't optimized yet), so it cannot prove a prerendered route is safe to drop: a route can be prerendered for GET yet still need runtime SSR (e.g. a POSTaction$, whichisStaticPathdoes not intercept). The option is therefore a user certification, and v1 is limited to static (non-dynamic) routes to avoid partial-prerender edge cases. Default behavior is byte-identical (empty list).Checklist
pnpm changeAI-assisted (Opus 4.8), could use a more thorough review.