GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Incremental hydration drops an event caught inside a block whose viewport hydration already started · Issue #72006 · angular/angular

Incremental hydration drops an event caught inside a block whose viewport hydration already started #72006

New issue
Copy link
New issue
Copy link
Open
Open
Incremental hydration drops an event caught inside a block whose viewport hydration already started#72006
Copy link
Labels
area: coreIssues related to the framework runtimeIssues related to the framework runtime
Milestone
needsTriage

Description

@Haembina
Haembina
opened on Nov 12, 2026
Issue body actions

Which @angular/ package(s) are the source of the bug?* core

Is this a regression? No

Description

With withIncrementalHydration() and @defer (hydrate on viewport), a click or keydown on an element inside the block is lost when it arrives after the viewport trigger started hydrating the block but before hydration finished.

hydrateAndInvokeBlockListeners (packages/core/src/hydration/event_replay.ts) queues the event and calls triggerHydrationFromBlockName(injector, blockName, replayFn). Because the viewport trigger already put the block in dehydratedBlockRegistry.hydrating, triggerHydrationFromBlockName (packages/core/src/defer/triggering.ts) returns at:

if (blocksBeingHydrated.has(blockName)) {
  return;
}

The in-flight hydration was started by the viewport trigger with no replayQueuedEventsFn, so nothing replays the queue when it finishes. The event stays in EVENT_REPLAY_QUEUE until some later event-triggered hydration happens to flush it, or forever.

Present in 22.2.6 and on main.

Reproduction (seen in a production app; these steps are the reduced shape, not yet a standalone StackBlitz)

  1. SSR app with provideClientHydration(withIncrementalHydration()).
  2. @defer (hydrate on viewport) { <button (click)="count = count + 1">{{ count }}</button> } below the fold, with a lazily loaded dependency so hydration takes a few hundred ms (throttle the network).
  3. Scroll the block into view and click the button immediately, before hydration finishes.

Expected: the click is replayed after hydration and count becomes 1. Actual: count stays 0.

Proposed fix

When the block is already hydrating, replay the queued events once that hydration settles:

const hydrating = blocksBeingHydrated.get(blockName);
if (hydrating) {
  if (replayQueuedEventsFn) {
    hydrating.promise.then(() => replayQueuedEventsFn([blockName]), () => {});
  }
  return;
}

createReplayQueuedBlockEventsFn already requeues events for blocks not in the list, so passing [blockName] replays only this block's events.

Activity

  1. angular-robot
    added
    area: coreIssues related to the framework runtimeIssues related to the framework runtime
    on Nov 12, 2026
  2. angular-robot
    added this to the needsTriage milestone on Nov 12, 2026
  3. ngbot
    added this to the needsTriage milestone on Nov 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: coreIssues related to the framework runtimeIssues related to the framework runtime

    Type

    No type

    Projects

    No projects

      Milestone

      • needsTriageNo due date

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.