fix(framework): trust SSR conditional content during hydration#286
Merged
Conversation
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>
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>
akroshg
reviewed
May 8, 2026
| */ | ||
| private $hasContentAfterMarker(anchor: Comment, endData: string): boolean { | ||
| let sibling = anchor.nextSibling; | ||
| while (sibling) { |
Contributor
There was a problem hiding this comment.
WE would loop only once, why while loop?
akroshg
approved these changes
May 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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:
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.