Skip to content

Fix auto-pause when circuit starts after enhanced navigation - #68540

Open
surya3655 wants to merge 2 commits into
dotnet:mainfrom
surya3655:68337-auto-pause
Open

Fix auto-pause when circuit starts after enhanced navigation#68540
surya3655 wants to merge 2 commits into
dotnet:mainfrom
surya3655:68337-auto-pause

Conversation

@surya3655

Copy link
Copy Markdown
Contributor

Description

Blazor auto-pause is not activated when the circuit starts after enhanced navigation from an initially static (non-interactive) page. Hiding the tab does not pause the circuit, and the SignalR connection stays active.

This change re-discovers the server-emitted browser configuration at circuit start and makes the auto-pause initializer tolerant of both options shapes, so auto-pause activates consistently whether the interactive page is reached on initial load or through enhanced navigation.


Root Cause

The circuit starts lazily — only when the first interactive Server/Auto component is discovered, which for a static-first page happens during enhanced navigation, after the web initializers have already run. Three things then compound:

  1. Stale options. The circuit options were resolved once at static startup, when no <!--Blazor-Configuration:...--> comment was present, so they never carried the auto-pause settings.
  2. No re-merge. The server does re-emit the configuration on the enhanced-navigation response, but the client never merged it back into the circuit options.
  3. Wrong lookup shape. The auto-pause initializer read its keys from options.circuit, which is undefined on the server startup path where CircuitStartOptions is passed directly — so even correct configuration would not have been read.

Result: beforeServerStart received stale (or unreadable) configuration, config was never set, and AutoPauseManager was never created — so no visibilitychange listener was registered.


Output

Before

Screen.Recording.2026-08-14.194642.mp4

After

Screen.Recording.2026-08-14.192435.mp4

Test Output

image image

Fix Details

File Change
src/Components/Web.JS/src/Boot.Server.Common.ts Re-discover the browser configuration present in the document and merge it into the circuit options in startServerCore, before the server initializers run.
src/Components/Server.AutoPause/src/js/autopause.lib.module.ts Read the auto-pause keys from whichever options shape is supplied, so configuration is applied on both the web and server startup paths.

afterWebStarted / afterServerStarted already dispose any previous manager before creating a new one, so re-configuration at circuit start cannot accumulate listeners.


Tests

  • AutoPauseInitializer.test.tsserver start reads auto-pause configuration discovered during enhanced navigation: with no configuration at web start no listener is registered; supplying configuration at server start registers exactly one.
  • BlazorWebJsInitializersTest.csServerInitializerActivatedAfterEnhancedNavigationFromStaticPage: loads a static page (asserting Blazor.pauseCircuit is undefined), enhanced-navigates to an interactive page, then dispatches visibilitychange and asserts pauseCircuit is invoked exactly once.

Verified by reverting the source changes locally: both tests fail.


Notes

  • Circuit start is the right point to apply the configuration: it coincides with the moment interactivity begins, when the interactive page's configuration comment is already present in the DOM.
  • Merging the flat server extension keys onto the circuit options mirrors the existing convention Boot.Web.ts uses on the initial startup path.
  • No change to WebAssembly configuration handling, and no change to the initial-load path where an interactive component is already present.
  • Why not fix this server-side (by emitting the configuration comment on static pages): that would make the configuration available at boot, but would not address point 3 above — beforeServerStart would still read the wrong options shape on the classic Blazor Server path. Handling it at circuit start fixes both.

Fixes #68337.

@dotnet-policy-service dotnet-policy-service Bot added the community-contribution Indicates that the PR has been added by a community member label Aug 14, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Thanks for your PR, @surya3655. Someone from the team will get assigned to your PR shortly and we'll get it reviewed.

@dotnet-policy-service
dotnet-policy-service Bot deployed to copilot-pat-pool August 14, 2026 14:26 Active
@dotnet-policy-service
dotnet-policy-service Bot deployed to copilot-pat-pool August 14, 2026 14:26 Active
@sheiksyedm sheiksyedm added the area-blazor Includes: Blazor, Razor Components label Aug 14, 2026
@sheiksyedm
sheiksyedm requested a lite review from Copilot August 14, 2026 14:43
@surya3655
surya3655 marked this pull request as ready for review August 14, 2026 14:43
@surya3655
surya3655 requested a review from a team as a code owner August 14, 2026 14:43

Copilot AI left a comment

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.

Pull request overview

This PR fixes Blazor Server AutoPause not activating when interactivity (circuit start) happens only after enhanced navigation from an initially static page. It ensures the server-emitted browser configuration discovered during enhanced navigation is merged into the circuit options before server startup initializers run, and updates the AutoPause initializer to handle both the “web” and “server” options shapes consistently.

Changes:

  • Add an enhanced-navigation hook to observe the newly received HTML document and re-merge server-emitted browser configuration into existing startup options.
  • Defer final circuit option resolution until server startup so configuration discovered later (during enhanced navigation) is included.
  • Update AutoPause JS initializer to read configuration from either options.circuit (web-start shape) or directly from options (server-start shape), with new test coverage (unit + E2E).

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/Components/Web.JS/src/Services/NavigationEnhancement.ts Adds a documentReceived callback so consumers can inspect the parsed HTML document before DOM sync.
src/Components/Web.JS/src/Boot.Web.ts Merges browser configuration on initial load and on enhanced navigation (via documentReceived) so late-discovered config is applied.
src/Components/Web.JS/src/Boot.Server.Common.ts Defers resolving circuit options until server startup, allowing enhanced-navigation config merges to be reflected when the circuit starts.
src/Components/test/testassets/Components.TestServer/RazorComponents/App.razor Adds query-controlled browser configuration emission for AutoPause to support E2E validation scenarios.
src/Components/test/E2ETest/ServerRenderingTests/BlazorWebJsInitializersTest.cs Adds an E2E regression test covering circuit start after enhanced navigation from a static page and verifying pauseCircuit is invoked.
src/Components/Server.AutoPause/src/js/test/AutoPauseInitializer.test.ts Adds a unit test validating server-start configuration enables AutoPause even if web-start config didn’t.
src/Components/Server.AutoPause/src/js/autopause.lib.module.ts Reads AutoPause configuration from either options shape and exports a real beforeServerStart handler.

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-blazor Includes: Blazor, Razor Components community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Blazor AutoPause doesn't initialize when Interactive Server starts after enhanced navigation

3 participants