Skip to content

fix(framework): trust SSR conditional content during hydration#286

Merged
mohamedmansour merged 3 commits into
mainfrom
fix/ssr-conditional-hydration
May 8, 2026
Merged

fix(framework): trust SSR conditional content during hydration#286
mohamedmansour merged 3 commits into
mainfrom
fix/ssr-conditional-hydration

Conversation

@mohamedmansour
Copy link
Copy Markdown
Contributor

@mohamedmansour mohamedmansour commented Apr 30, 2026

When hydrating a conditional block, the framework previously required the runtime condition value to be truthy before wiring up SSR content. This caused duplicate DOM when a condition depended on complex properties (like :data) set by the parent AFTER the child hydrates:

  1. SSR renders content (condition was true on server)
  2. Child hydrates — complex prop not yet set — condition evaluates false
  3. SSR DOM nodes left orphaned (not wired, not removed)
  4. Parent sets complex prop — condition becomes true — new nodes created
  5. Result: duplicate content visible to the user

Fix: during SSR hydration, if a marker has content after it (the server rendered the block), hydrate that content regardless of the current condition value. The server was authoritative; the data will arrive from the parent and the condition will reconcile correctly.

Added helper to detect SSR content between conditional markers.

mohamedmansour and others added 2 commits April 30, 2026 13:19
When hydrating a conditional block, the framework previously required
the runtime condition value to be truthy before wiring up SSR content.
This caused duplicate DOM when a condition depended on complex
properties (like :data) set by the parent AFTER the child hydrates:

1. SSR renders content (condition was true on server)
2. Child hydrates — complex prop not yet set — condition evaluates false
3. SSR DOM nodes left orphaned (not wired, not removed)
4. Parent sets complex prop — condition becomes true — new nodes created
5. Result: duplicate content visible to the user

Fix: during SSR hydration, if a <!--wc--> marker has content after it
(the server rendered the block), hydrate that content regardless of the
current condition value. The server was authoritative; the data will
arrive from the parent and the condition will reconcile correctly.

Added \() helper to detect SSR content between
conditional markers.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…plex props

Extends the complex-prop fixture with a test-cond-child component that
has a conditional block driven by :data.showHeader. Three tests verify:

- SSR conditional content is hydrated without duplicates (the core
  regression: child hydrates before parent sets :data, condition
  evaluates false, but SSR content must be preserved)
- SSR conditional text matches the state.json value
- Toggling :data.showHeader to false correctly removes the block

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mohamedmansour mohamedmansour requested a review from akroshg April 30, 2026 20:38
During SSR hydration, $hydrateCondContent was calling $updateInstance
which evaluated text bindings with stale/missing data.  When a child
component's conditional block depended on a complex property (:data)
from a parent that hadn't hydrated yet, the text nodes were overwritten
from their correct SSR values to empty strings.

Remove the $updateInstance calls from $hydrateCondContent — SSR text
nodes already contain the correct server-rendered values.  This is
consistent with $mount which also skips $updateInstance for SSR roots.
The bindings are wired and will update reactively once data arrives.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mohamedmansour mohamedmansour requested a review from a team May 8, 2026 04:17
*/
private $hasContentAfterMarker(anchor: Comment, endData: string): boolean {
let sibling = anchor.nextSibling;
while (sibling) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

WE would loop only once, why while loop?

@mohamedmansour mohamedmansour merged commit c40db82 into main May 8, 2026
21 checks passed
@mohamedmansour mohamedmansour deleted the fix/ssr-conditional-hydration branch May 8, 2026 06:37
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