Skip to content

fix(pages): collect CSS from dynamicImports to prevent FOUC - #26

Merged
Brooooooklyn merged 1 commit into
mainfrom
fix/pages-css-fouc
Mar 25, 2026
Merged

Brooooooklyn merged 1 commit into
mainfrom
fix/pages-css-fouc

Conversation

@Brooooooklyn

@Brooooooklyn Brooooooklyn commented Mar 24, 2026 •

Copy link
Copy Markdown
Member

collectPagesManifestFiles only traversed chunk.imports, missing CSS
from dynamically imported modules like layouts. Since layouts are
listed under dynamicImports in the Vite manifest, their CSS was never
injected as in , causing a flash of
unstyled content on every page load.

Now traverses both imports and dynamicImports so layout CSS is
included in the initial HTML response.

Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com


Note

Medium Risk
Medium risk because it changes server-rendered asset tag generation and response short-circuiting for pages, which can affect styling and HTTP behavior across all routes if manifest keys or component IDs are wrong.

Overview
Fixes missing/incorrect CSS injection for Pages SSR by changing asset-tag generation to be route-aware: the compiler now precomputes PAGE_CSS_KEYS (page + resolved layout chain) and uses a new collectRouteCss() helper to pull CSS for the active componentId from the Vite manifest.

This threads componentId through getPagesAssetTags/getIslandsAssetTags and their callers, adds pagesDirRelative to ensure manifest key lookup matches Vite’s paths, and updates GET handling to return early for any Response with status >= 300 (not just redirects).

Written by Cursor Bugbot for commit 5bf78ec. This will update automatically on new commits. Configure here.

Copy link
Copy Markdown
Member Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

Comment thread packages/void/src/router/compile.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 09cbd85c0f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/void/src/router/compile.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f07a61a88d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/void/src/router/compile.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d93fb738c5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/void/src/router/compile.ts

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Comment thread packages/void/src/router/compile.ts
The previous collectDynamicCss walked all dynamicImports from the pages
client entry, which included every page and layout in the app. This
defeated CSS code splitting — rendering /about would emit stylesheet
links for /users, /dashboard, and every other page.

Replace with collectRouteCss: a two-phase walk that collects CSS from
(1) the entry's static imports (shared/global CSS) and (2) only the
active page's chunk and its layout chain's chunks. A build-time
PAGE_CSS_KEYS mapping provides the manifest keys for each componentId.

getPagesAssetTags and getIslandsAssetTags now accept componentId so they
can look up the correct keys. The protocol layer threads componentId
through the getAssetTags callback in both handlePageGet and
handlePageMutation.

pagesDirRelative is normalized to POSIX separators so manifest key
lookups work correctly on Windows.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Brooooooklyn
Brooooooklyn merged commit 8d51c48 into main Mar 25, 2026
8 checks passed
@Brooooooklyn
Brooooooklyn deleted the fix/pages-css-fouc branch March 25, 2026 03:13
cpojer pushed a commit that referenced this pull request Sep 11, 2026
)

* ci: add schema-compat job to catch backward-incompatible migrations

During deploy, drizzle-kit migrate runs before the new API worker goes
live. The schema-compat CI job catches breaking migrations by applying
the PR's migrations to real PostgreSQL 17, then running the prod
branch's tests against the new schema.

Test helpers now fork on DATABASE_URL: real pg.Pool when set, PGlite
when unset (existing behavior preserved). Integration tests run
sequentially (fileParallelism: false) when using real PG to avoid
data races on the shared database.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* ci: clean untracked PR files after prod checkout

git clean -fd after the phase 2 checkout removes files that exist in
the PR branch but not in prod, preventing spurious test failures from
orphaned test files picked up by vitest globs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
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.

1 participant