Skip to content

Sync Blazor templates with aspnetcore net11-pre4 - #35265

Closed
mattleibow wants to merge 5 commits into
net11.0from
mattleibow/blazor-template-sync-net11-pre4
Closed

Sync Blazor templates with aspnetcore net11-pre4#35265
mattleibow wants to merge 5 commits into
net11.0from
mattleibow/blazor-template-sync-net11-pre4

Conversation

@mattleibow

Copy link
Copy Markdown
Member

Note

Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!

Description

Syncs both MAUI Blazor templates (maui-blazor and maui-blazor-web) with upstream changes from dotnet/aspnetcore BlazorWeb-CSharp template (release/10.0main/net11-pre4).

Changes

Both templates

  • NavMenu.razor: Replace inline onclick handler with id="nav-scrollable" + JS module (CSP compliance)
  • NEW NavMenu.razor.js: Co-located JS click handler for nav toggle
  • template.json: Add **/*.razor.js to copyOnly so template engine emits co-located JS files

maui-blazor (standalone)

  • index.html: Add <script> reference for NavMenu.razor.js

maui-blazor-solution (multi-project)

  • App.razor: <base href="/" /><BasePath /> component
  • ReconnectModal.razor: Resume button ordering + resume-failed-visible class
  • ReconnectModal.razor.js: Resume failure shows state instead of force-reload
  • ReconnectModal.razor.css: Fix &[open] CSS nesting indentation
  • Error.razor: [PersistentState] on RequestId, public, ??= assignment
  • _Imports.razor (Web): Add @using Microsoft.AspNetCore.Components.Endpoints
  • template.json: Add onlyIf localhost constraint on port replacers
  • Web.Client Program.cs/Main.cs: PersistentAuthenticationStateProviderAddAuthenticationStateDeserialization()
  • index.html: Add NavMenu.razor.js script reference

Not synced (intentional)

  • Account/Identity pages (not in MAUI templates)
  • Data/migrations (not in MAUI templates)
  • Localize files (auto-generated)

Copilot AI review requested due to automatic review settings April 30, 2026 19:20
@github-actions

github-actions Bot commented Apr 30, 2026

Copy link
Copy Markdown
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 35265

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 35265"

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.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

Apply upstream changes from dotnet/aspnetcore BlazorWeb-CSharp template
(release/10.0 → main/net11-pre4) to both maui-blazor and
maui-blazor-solution templates:

- ReconnectModal.razor: Resume button ordering + resume-failed class
- ReconnectModal.razor.js: Show resume-failed state instead of reload
- ReconnectModal.razor.css: Fix &[open] CSS nesting indentation
- Web.Client Program.cs/Main.cs: Use AddAuthenticationStateDeserialization()
- template.json: Add onlyIf localhost constraint on port replacers
- template.json: Add *.razor.js to copyOnly for co-located JS files
- index.html: Add SampleContent-guarded NavMenu.razor.js script refs

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mattleibow
mattleibow force-pushed the mattleibow/blazor-template-sync-net11-pre4 branch from 72b817b to ce11f67 Compare May 7, 2026 21:25
@MauiBot

This comment has been minimized.

@kubaflo

kubaflo commented May 24, 2026

Copy link
Copy Markdown
Contributor

/review -b feature/refactor-copilot-yml

@MauiBot

This comment has been minimized.

@kubaflo

kubaflo commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

AI code review for net11.0 target

Verdict: LGTM

Template-only sync of the Blazor (maui-blazor, maui-blazor-solution) templates with aspnetcore net11-pre4.

Key findings

  • copyOnly now includes **/*.razor.js, and the new <script> references (Components/Layout/NavMenu.razor.js and _content/MauiApp.1.Shared/Layout/NavMenu.razor.js) resolve to files that do exist at the PR head — no dangling reference / 404.
  • kestrelHttpPort/kestrelHttpsPort now carry onlyIf: after "localhost:", correctly scoping port substitution to the localhost:5500/5501 occurrences instead of any literal 5500/5501.
  • Auth wiring swap to AddAuthenticationStateDeserialization() and the ReconnectModal markup/CSS/JS changes mirror the upstream aspnetcore templates; resume-failed UX is an improvement over forced reload.
  • No blocking code issues found.

CI note: Most legs green. The RunOniOS_*Release/TrimFull + AOT failures also appear on unrelated net11 PRs in this batch, so they read as shared infra/flaky failures rather than template-caused. Integration Blazor/Build/Samples legs (the ones that actually exercise these templates) pass.

Confidence: High.

This is an automated, non-approval review comment, not a GitHub approval/request-changes. A human must make the merge decision.

@kubaflo kubaflo 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.

Cross-model synthesis — dotnet/maui PR #35265 (Sync Blazor templates with aspnetcore net11-pre4)

Verdict: NEEDS_CHANGES (confidence: medium)

gpt-5.5's lone finding is CONFIRMED real, not a false positive. The added index.html module reference (maui-blazor/wwwroot/index.html:30 and maui-blazor-solution/MauiApp.1/wwwroot/index.html:25) is a deferred type="module" script that evaluates during the initial WebView page load; because MAUI Hybrid has no prerendering and uses autostart="false", the NavMenu has not been rendered into #app yet, so NavMenu.razor.js's one-shot getElementById("nav-scrollable") returns null, the if guard short-circuits (no null-ref, but no listener attaches), and it never re-runs — the mobile nav auto-collapse that net10's inline onclick provided is not restored in generated Hybrid apps. This is not mitigated by defer/DOMContentLoaded/event-delegation and does NOT match the upstream mechanism (which works only via SSR prerendering, absent in Hybrid); the pattern exists in no shipping branch (net10.0, net11.0 base, release/10.0.1xx, main). The other 8 changed lines (copyOnly **/*.razor.js, onlyIf localhost port guard, AddAuthenticationStateDeserialization(), ReconnectModal razor/css/js) are verified correct as the 3 other models found.

CI: maui-pr is RED — Build Analysis + RunOniOS_*Release/TrimFull(_CoreCLR) + AOT macOS legs fail; these exercise the plain MAUI template (not these Blazor files) and read as shared infra/flaky (Blazor/Build/Samples/MultiProject/WindowsTemplates legs pass). Verdict is driven by the confirmed finding, not CI.

Comment thread src/Templates/src/templates/maui-blazor/wwwroot/index.html
Use document-level event delegation so the generated Hybrid templates
attach the collapse behavior even when the module loads before Blazor
renders the NavMenu.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 14, 2026 03:11

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

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

@kubaflo

This comment has been minimized.

@github-actions github-actions Bot added the s/agent-review-in-progress AI review is currently running for this PR label Jul 14, 2026

@MauiBot MauiBot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Expert Review — 2 findings

See inline comments for details.

@MauiBot MauiBot added s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) labels Jul 14, 2026
MauiBot

This comment was marked as outdated.

@MauiBot MauiBot removed the s/agent-review-in-progress AI review is currently running for this PR label Jul 14, 2026
Use the existing WebAssembly package version token for the auth
package so generated auth-enabled Web.Client projects can call
AddAuthenticationStateDeserialization.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 14, 2026 04:38

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

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Comment thread src/Templates/src/templates/maui-blazor/wwwroot/index.html
Only forward delegated nav clicks to the hidden checkbox when the
mobile menu is already open, so desktop nav clicks do not leave the
menu pre-opened after a later resize.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 14, 2026 05:36

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

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

@kubaflo

This comment has been minimized.

@github-actions github-actions Bot added the s/agent-review-in-progress AI review is currently running for this PR label Jul 14, 2026

@MauiBot MauiBot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

AI Review Summary

@mattleibow — new AI review results are available based on this last commit: 6a393d2. To request a fresh review after new comments or commits, comment /review rerun.

Gate No Tests Confidence Low Platform Android


🗂️ Review Sessions — click to expand
🚦 Gate — Test Before & After Fix

Gate Result: ⚠️ SKIPPED

No tests were detected in this PR.

Recommendation: Add tests to verify the fix using the write-tests-agent.


📋 Pre-Flight — Context & Validation

Issue: #35265 - MAUI Blazor Hybrid NavMenu collapse timing
PR: #35265 - Fix MAUI Blazor Hybrid NavMenu collapse
Platforms Affected: Android (requested), plus all MAUI Blazor Hybrid hosts generated from these templates
Files Changed: 12 implementation/template, 0 test

Key Findings

  • GitHub CLI is unauthenticated, so PR metadata/comments/checks were gathered from the local squashed PR commit and public patch content instead of authenticated GitHub APIs.
  • The PR fix changes NavMenu collapse from one-shot element binding to guarded document-level delegation because Hybrid can load NavMenu.razor.js before Blazor renders the menu.
  • Gate result was already skipped because no tests were detected; no gate rerun was performed.
  • Impacted UI categories: Template / Blazor Hybrid generated app navigation; no canonical UI test category was selected because this is a template JavaScript behavior change, not a Controls UITest category.

Code Review Summary

Verdict: NEEDS_DISCUSSION
Confidence: low
Errors: 0 | Warnings: 1 | Suggestions: 1

Key code review findings:

  • ⚠ No regression coverage for generated Hybrid NavMenu collapse when the module loads before the rendered menu exists.
  • ℹ The duplicate script-loading surfaces are safe due to the global guard but would benefit from clarification or simplification.

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #35265 Load NavMenu module from Hybrid index.html and use guarded document-level delegated click handling that only toggles when the checkbox is checked. ⚠️ SKIPPED (Gate: no tests detected) NavMenu.razor.js, index.html, template config and upstream sync files Original PR

🔬 Code Review — Deep Analysis

Code Review — PR #35265

Independent Assessment

What this changes: The PR syncs MAUI Blazor templates with upstream ASP.NET Core template changes and fixes the Hybrid NavMenu collapse behavior by copying colocated .razor.js files, loading NavMenu.razor.js from Hybrid index.html, and changing the NavMenu script to a guarded document-level delegated click handler.
Inferred motivation: In MAUI Blazor Hybrid, blazor.webview.js is loaded with autostart="false" and #app initially contains Loading...; a module loaded from index.html can run before Blazor renders #nav-scrollable, so the previous one-shot element lookup attached no listener.

Reconciliation with PR Narrative

Author claims: Public patch commits describe syncing upstream Blazor template changes and fixing MAUI Blazor Hybrid NavMenu collapse by using document-level event delegation so the behavior attaches even when the module loads before Blazor renders the menu.
Agreement/disagreement: Local code agrees with that root cause. The final PR version also avoids opening the menu from desktop nav clicks by forwarding only when .navbar-toggler.checked is true.

Prior Review Reconciliation

Prior ❌ Error Finding Source Status Evidence
NavMenu script can run before #nav-scrollable exists and fail to attach collapse behavior Public patch commit narrative / local expert review ✅ Fixed Both NavMenu.razor.js files now use document.addEventListener("click", ...) and resolve elements when clicks occur.
Auth-enabled Web.Client template used an incompatible hard-coded WebAssembly auth package version Public patch commit narrative / local expert review ✅ Fixed MauiApp.1.Web.Client.csproj now uses MS_COMPONENTS_WEBASSEMBLY_VERSION.

Blast Radius Assessment

  • Runs for all instances: Yes, but only generated maui-blazor and maui-blazor-web projects with sample content load the NavMenu script.
  • Startup impact: Yes, Hybrid index.html now imports the NavMenu module before Blazor renders app content.
  • Static/shared state: Yes, globalThis.__mauiNavMenuCollapseInitialized suppresses duplicate document handlers across duplicate module imports.

CI Status

  • Required-check result: undetermined; gh is unauthenticated in this environment.
  • Classification: undetermined.
  • Action taken: capped confidence; gate was already skipped because no tests were detected.

Findings

⚠️ Warning — No regression coverage for the Hybrid NavMenu timing bug

The PR adds no test proving generated Hybrid apps collapse the mobile nav when NavMenu.razor.js loads before Blazor renders #nav-scrollable. This risk applies to src/Templates/src/templates/maui-blazor/Components/Layout/NavMenu.razor.js and src/Templates/src/templates/maui-blazor-solution/MauiApp.1.Shared/Layout/NavMenu.razor.js.

💡 Suggestion — Consider documenting or simplifying the two script-loading surfaces

Hybrid index.html loads the NavMenu script early, while the component also retains a script tag. The guarded global flag makes this safe, but future maintainers may need context on why both surfaces exist.

Failure-Mode Probing

  • Module loads before NavMenu exists: current PR succeeds because it binds to document and resolves targets at click time.
  • Desktop nav click when checkbox is unchecked: current PR does not call click() because it requires an HTMLInputElement with checked === true.
  • Duplicate imports from index.html and component script tag: current PR suppresses duplicate listeners with a globalThis flag.

Verdict: NEEDS_DISCUSSION

Confidence: low (CI/check status unavailable and no regression test was added.)
Summary: The PR’s delegated handler is directionally sound for the Hybrid timing problem. The main remaining risk is lack of regression coverage for generated template behavior.


🛠️ Fix — Analysis & Comparison

Fix Candidates

# Source Approach Test Result Files Changed Notes
1 try-fix Scoped late binding with requestAnimationFrame; wait for rendered NavMenu elements, then attach listener directly to #nav-scrollable. ✅ PASS 2 JS files Avoids document-level delegation but adds a polling loop and depends on stable element identity. Not better than PR.
2 try-fix MutationObserver late binding; observe until NavMenu appears, bind direct listener, disconnect. ✅ PASS 2 JS files Avoids permanent document click listener but is more complex and depends on document.body. Not better than PR.
3 try-fix Delegated direct state reset; keep timing-safe delegation but set navToggler.checked = false instead of calling click(). ✅ PASS 2 JS files Plausible simplification that avoids synthetic click side effects, but assumes no future checkbox click/change listeners are needed.
PR PR #35265 Load NavMenu module from Hybrid index.html and use guarded document-level delegated click handling that only toggles when the checkbox is checked. ⚠️ SKIPPED (Gate: no tests detected) 12 template files Original PR; simplest robust timing fix among scoped alternatives.

Cross-Pollination

Model/Reviewer Round New Ideas? Details
maui-expert-reviewer 1 Yes Suggested late startup hook, MutationObserver/init-on-render, Blazor-native collapse state, and direct checked = false reset as alternatives.
local test loop 2 No After testing the three materially different viable strategies, remaining Blazor-native/component-script approaches were not pursued because they either reintroduce the original dynamically-rendered script timing risk or diverge substantially from upstream template structure.

Exhausted: Yes
Selected Fix: PR #35265 — The tested alternatives pass the local timing simulation and template build, but none is demonstrably better overall. Candidate #3 is the strongest alternative if avoiding synthetic checkbox clicks is preferred, but the PR’s click() path better preserves checkbox event semantics if future template code observes those events.

Test Command Used

node <session>/files/navmenu-*.mjs <NavMenu.razor.js>
dotnet build src/Templates/src/Microsoft.Maui.Templates.csproj --no-restore --nologo --verbosity:minimal

Candidate #1 initially hit a missing restore asset, then passed after dotnet build src/Templates/src/Microsoft.Maui.Templates.csproj restored assets. Candidates #2 and #3 used the restored assets and passed with --no-restore.

Environment Notes

  • gh was unauthenticated, so PR comments/checks could not be fetched via GitHub CLI.
  • EstablishBrokenBaseline.ps1 was blocked by pre-existing dirty files outside the PR/template files, so baseline setup was recorded as blocked and the loop continued with isolated patches against the local PR state.
  • Gate verification was not rerun, per instruction; gate was already skipped because no tests were detected.

📝 Recommended PR Title & Description

Assessment: ✏️ Recommend updating — the description is detailed but stale: it lists App.razor/BasePath, Error.razor, _Imports.razor, and other changes that are not present in the actual diff.

Recommended title

[Templates] Blazor Hybrid: Sync MAUI Blazor templates with aspnetcore net11-pre4

Recommended description

## Description

Syncs both MAUI Blazor templates (`maui-blazor` and `maui-blazor-web`) with upstream `dotnet/aspnetcore` Blazor template changes for net11-pre4.

## Changes

### Both templates
- **NavMenu.razor.js**: Use a guarded document-level delegated click handler so the mobile NavMenu collapse logic still works when the module loads before Blazor renders `#nav-scrollable`.
- **index.html**: Load `NavMenu.razor.js` from the Hybrid host when sample content is included.
- **template.json**: Add `**/*.razor.js` to `copyOnly` so the template engine emits co-located JavaScript files.

### `maui-blazor-web` / multi-project template
- **template.json**: Add `onlyIf` localhost constraints on the Kestrel port replacers.
- **Web.Client csproj**: Use `MS_COMPONENTS_WEBASSEMBLY_VERSION` for `Microsoft.AspNetCore.Components.WebAssembly.Authentication`.
- **Web.Client Program.cs / Program.Main.cs**: Replace `PersistentAuthenticationStateProvider` registration with `AddAuthenticationStateDeserialization()`.
- **ReconnectModal.razor**: Update resume failure UI so users can retry or reload.
- **ReconnectModal.razor.js**: Show resume-failed state on resume exceptions instead of immediately reloading.
- **ReconnectModal.razor.css**: Fix `&[open]` CSS nesting formatting.

### Not synced / not included
- Account/Identity pages and data/migrations that are not part of the MAUI templates.
- Localization files and other generated template assets.

## Testing

Gate was skipped because no tests were detected. Android is the target platform for validating the Hybrid NavMenu collapse timing behavior.

🏁 Report — Final Recommendation

Comparative Fix Report

Candidate ranking

Rank Candidate Regression evidence Assessment
1 pr Gate skipped; no tests detected Best overall. The delegated handler is the simplest timing-safe fix, preserves checkbox click/change semantics by using navToggler.click(), and aligns with the template sync intent. Expert review found no actionable code findings.
2 pr-plus-reviewer Gate skipped; no tests detected Production-code-identical to pr because expert reviewer feedback was coverage-only. Equivalent behavior, but not a distinct stronger fix.
3 try-fix-3 ✅ Passed Node timing simulation and template build Strongest alternate. It keeps timing-safe delegation but directly assigns navToggler.checked = false; this avoids synthetic clicks, but is a narrower behavior bet if future template code observes checkbox click/change events.
4 try-fix-1 ✅ Passed Node timing simulation and template build Correct but less attractive. requestAnimationFrame late binding avoids document delegation, but adds a recurring retry loop until render and assumes the initially found elements remain the right binding targets.
5 try-fix-2 ✅ Passed Node timing simulation and template build Correct but more complex. MutationObserver late binding avoids a permanent document listener, but adds observer lifecycle complexity and depends on document.body being available.

No candidate failed regression tests, so no failing candidate was ranked above a passing one.

Winning candidate: pr

The raw PR fix should win. It directly solves the Hybrid script-load timing issue by moving from startup-time DOM lookup to event-time DOM lookup, while the global guard prevents duplicate handler registration from the NavMenu.razor and index.html module references. The alternatives demonstrate viable implementations, but each introduces a tradeoff that is not clearly better than the PR: polling, mutation observation, or direct state assignment that bypasses checkbox event semantics.

Notes for the PR author

The remaining weakness is test coverage, not the fix shape. The PR should ideally add or document regression coverage for the Android/Hybrid case where NavMenu.razor.js loads before Blazor renders #nav-scrollable; gate verification was skipped because no tests were detected.


🧭 Next Steps — review latest findings

No alternative fix was selected for this run. Review the session findings and CI results before merging.

@MauiBot MauiBot removed the s/agent-review-in-progress AI review is currently running for this PR label Jul 14, 2026
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 14, 2026 18:47
@kubaflo

This comment has been minimized.

@kubaflo

kubaflo commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

🔍 This is an AI-generated comment posted on @kubaflo's behalf.

✓ Clarified the intentional dual NavMenu.razor.js load in commit 6daac0c: the script is loaded both from the collocated component and early from index.html so the document-level delegated collapse handler is registered before Hybrid renders the menu, and the existing globalThis.__mauiNavMenuCollapseInitialized guard keeps listener registration idempotent.

ℹ For the test-gap warning: this remains a template JavaScript behavior change rather than a Controls UITest scenario. I checked the template integration coverage path; it can build/run generated templates, but it does not provide a reliable normal-infra regression hook for this DOM timing/click behavior, so I did not fabricate a test.

@github-actions github-actions Bot added s/agent-review-in-progress AI review is currently running for this PR and removed s/agent-review-in-progress AI review is currently running for this PR labels Jul 14, 2026

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

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

@mattleibow mattleibow closed this Jul 29, 2026
@mattleibow

Copy link
Copy Markdown
Member Author

Closing as we need to redo this with things from aspnetcore pre 7

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

Labels

s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants