Skip to content

dx(ui): warn when hydration ends with unclaimed SSR nodes #623

@viniciusdacal

Description

@viniciusdacal

Description

When endHydration() is called, if the cursor hasn't reached the end of siblings at any level, the SSR and client trees diverged. The developer gets no feedback about this — extra SSR nodes are silently left in the DOM.

Context

  • In packages/ui/src/hydrate/hydration-context.ts, endHydration() (lines 33-37) resets all state without checking if nodes were left unclaimed:
    export function endHydration(): void {
      isHydrating = false;
      currentNode = null;
      cursorStack.length = 0;
    }
  • If the SSR output has <div><h1>Title</h1><p>Extra paragraph</p></div> but the client only claims <h1>, the <p> remains in the DOM unclaimed. This is correct behavior for tolerant mode (don't destroy extra content), but the developer should know their trees diverged.
  • The cursor stack may also have entries if enterChildren/exitChildren were unbalanced at end of hydration (separate from the empty-stack warning in exitChildren which fires mid-hydration).
  • This should be console.debug (not warn) since extra nodes from browser extensions are expected and normal.

Tasks

  1. Before resetting state in endHydration(), check if currentNode !== null (unclaimed siblings remain).
  2. Check if cursorStack.length > 0 (unbalanced enter/exit).
  3. Log appropriate dev-mode debug messages.

Files to modify

  • packages/ui/src/hydrate/hydration-context.tsendHydration()

References

Acceptance Criteria

  • Test: hydration ends with unclaimed sibling → console.debug with message like "[hydrate] Hydration ended with unclaimed nodes remaining. SSR tree may have extra content."
  • Test: hydration ends with unbalanced stack → console.debug with stack depth info
  • Test: clean hydration (all claimed, stack empty) → no debug output
  • Zero overhead in production builds
  • Browser extension nodes triggering this debug message is acceptable and expected

Progress

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal — planned workenhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions