Skip to content

fix(solid): preserve SSR DOM when hydrating islands - #488

Merged
Brooooooklyn merged 4 commits into
voidzero-dev:mainfrom
mizchi:fix/solid-island-hydration
Oct 19, 2026
Merged

Brooooooklyn merged 4 commits into
voidzero-dev:mainfrom
mizchi:fix/solid-island-hydration

Conversation

@mizchi

@mizchi mizchi commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

The current Solid island implementation calls render() instead of hydrate().

It clears the server HTML and replaces the DOM, discarding input entered before activation. This PR uses hydrate() with a matching SSR root for each island instance.

What this PR changes

  • Assign each island instance a unique renderId, scope its SSR hydration keys to that root, and store the ID in data-solid-render-id. The existing SSR serializer and Suspense state are retained, and the parent hydration context is restored in finally.
  • Use the same FrontmatterContext.Provider tree on the server and client, then call hydrate() with the stored ID without clearing the element.
  • Allow a delayed island to hydrate after another island handles an event. Solid 1.x sets document-wide completion flags on the first delegated event, so the adapter resets those flags before hydrating the next island.

The island import syntax and hydration scheduling API are unchanged.

Decisions for review

The implementation accesses Solid 1.x's sharedConfig.context, sharedConfig.done and globalThis._$HY.done. The latter two writes prevent a later hydrate() from falling back to client rendering after a click in an earlier island. This dependency on Solid's internal hydration state needs review, especially for other asynchronous hydration scenarios. Local verification used Solid 1.9.17.

Testing

The pre-fix DOM-reuse regression failed: both the button and input were replaced, and the input value was lost. The new browser suite passes all 6 cases across Vite dev and a production build/preview:

  • Repeated islands and an island layout retain the original button/input nodes, input values, label associations and frontmatter; counter state remains independent.
  • Two visible islands hydrate in reverse order after an earlier island handles a click.
  • An async resource inside Suspense retains its resolved SSR DOM and remains interactive.

vp run build:all, vp run check, vp lint, and the formatter check for the two changed files passed.

The full suite is not green locally: 13,895 passed, 18 failed, 27 skipped. The same 18 failures reproduced after restoring and rebuilding the base adapter at 83799305bbe4 and rerunning the three affected test files.

Validation commands and existing failures
vp test run packages/solid/test/integration/island-hydration.test.ts
vp run build:all
vp run check
vp lint
vp fmt --check packages/solid/src/plugin-islands.ts packages/solid/test/integration/island-hydration.test.ts
vp run test
vp test run

The failures are in:

  • packages/void/test/integration/init-install.test.ts: 3 failures.
  • packages/void/test/unit/init.test.ts: 14 failures.
  • packages/void/test/unit/nitro.test.ts: 1 failure.

The changed-file selection also completed: 10,598 passed, the same 18 failed, and 27 skipped. Live Cloudflare deployment credentials were unset during both suite runs.

Searched issues and PRs in all states for solid hydrate and hydration Solid; no matching report or fix was found.

AI disclosure

I used OpenAI Codex to implement the fix, write the regression tests, and prepare this PR description. The verification commands above were run locally.

@Brooooooklyn
Brooooooklyn self-requested a review October 19, 2026 04:26
mizchi and others added 3 commits October 19, 2026 13:30
The client must render the frontmatter provider even when the page has
no frontmatter: every createComponent call opens a hydration context, so
skipping the provider shifts the island's hydration keys and it never
hydrates. Add a production case for that page and say why in the client
entry.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@Brooooooklyn

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-19T07:15:51.035053Z 7219ea3 Manual request
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@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: 7219ea39cc

ℹ️ 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/solid/src/plugin-islands.ts

Brooooooklyn commented Oct 19, 2026 •

Copy link
Copy Markdown
Member

Merge activity

  • Oct 19, 8:00 AM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Oct 19, 8:00 AM UTC: Graphite couldn't merge this PR because it failed for an unknown reason (Fast-forward merges are not supported for forked repositories. Please create a branch in the target repository in order to merge).

@Brooooooklyn
Brooooooklyn merged commit 94bc987 into voidzero-dev:main Oct 19, 2026
18 checks passed
@mizchi
mizchi deleted the fix/solid-island-hydration branch October 19, 2026 17:52
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