Skip to content

feat(qwik-router): exclude prerendered routes from the server route plan#8742

Merged
wmertens merged 1 commit into
QwikDev:build/v2from
briancarbone:fix/exclude-prerendered-from-ssr-bundle
Jun 21, 2026
Merged

feat(qwik-router): exclude prerendered routes from the server route plan#8742
wmertens merged 1 commit into
QwikDev:build/v2from
briancarbone:fix/exclude-prerendered-from-ssr-bundle

Conversation

@briancarbone

@briancarbone briancarbone commented Jun 17, 2026

Copy link
Copy Markdown

What is it?

Description

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.

How it works

  • Matched with the existing createRouteTester (the same matcher SSG uses), so the glob syntax is identical to ssg.include.
  • In createRoutes, a matched static route's loader is skipped, so its trie node prunes and the route's chunk tree-shakes
    out. routeIdMap membership stays the single source of truth (the _R loader-hash emission now mirrors it).
  • A new @qwik-router-config?ssg virtual-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$/onRequest detection, 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 POST action$, which isStaticPath does 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

  • My code follows the developer guidelines of this project
  • I performed a self-review of my own code
  • I added a changeset with pnpm change
  • I made corresponding changes to the Qwik docs
  • I added new tests to cover the fix / functionality

AI-assisted (Opus 4.8), could use a more thorough review.

@briancarbone briancarbone requested a review from a team as a code owner June 17, 2026 03:46
@changeset-bot

changeset-bot Bot commented Jun 17, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: cf7776a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 5 packages
Name Type
@qwik.dev/router Minor
eslint-plugin-qwik Minor
@qwik.dev/core Minor
create-qwik Minor
@qwik.dev/react Minor

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

@briancarbone briancarbone changed the title feat(router): exclude prerendered routes from the server route plan feat(qwik-router): exclude prerendered routes from the server route plan Jun 17, 2026
@briancarbone

briancarbone commented Jun 17, 2026

Copy link
Copy Markdown
Author

This would be better implemented by detecting routes with non-GET server entry points; then you could have just ssg in the config while still generating the necessary server code. In any case, stripping prerendered routes from the bundle is actually required for me to stay within edge platform limits.

@briancarbone briancarbone marked this pull request as draft June 18, 2026 21:00
@briancarbone briancarbone force-pushed the fix/exclude-prerendered-from-ssr-bundle branch 3 times, most recently from 2509236 to 1a3e51e Compare June 19, 2026 22:49
@briancarbone briancarbone marked this pull request as ready for review June 19, 2026 22:58
@briancarbone briancarbone force-pushed the fix/exclude-prerendered-from-ssr-bundle branch 2 times, most recently from ee995fa to 25cae84 Compare June 20, 2026 01:43

@wmertens wmertens left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

@briancarbone briancarbone force-pushed the fix/exclude-prerendered-from-ssr-bundle branch 2 times, most recently from add0a75 to c8f37f7 Compare June 20, 2026 17:12
@pkg-pr-new

pkg-pr-new Bot commented Jun 20, 2026

Copy link
Copy Markdown

Open in StackBlitz

@qwik.dev/core

npm i https://pkg.pr.new/QwikDev/qwik/@qwik.dev/core@8742

@qwik.dev/router

npm i https://pkg.pr.new/QwikDev/qwik/@qwik.dev/router@8742

eslint-plugin-qwik

npm i https://pkg.pr.new/QwikDev/qwik/eslint-plugin-qwik@8742

create-qwik

npm i https://pkg.pr.new/QwikDev/qwik/create-qwik@8742

@qwik.dev/optimizer

npm i https://pkg.pr.new/QwikDev/qwik/@qwik.dev/optimizer@8742

commit: cf7776a

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.
@briancarbone briancarbone force-pushed the fix/exclude-prerendered-from-ssr-bundle branch from c8f37f7 to cf7776a Compare June 20, 2026 18:01
@github-actions

github-actions Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor
built with Refined Cloudflare Pages Action

⚡ Cloudflare Pages Deployment

Name Status Preview Last Commit
qwik-docs ✅ Ready (View Log) Visit Preview cf7776a

@wmertens wmertens left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@wmertens wmertens merged commit d3d3b17 into QwikDev:build/v2 Jun 21, 2026
48 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants