Skip to content

[release/9.0] [Blazor WASM standalone] Avoid caching index.html during development - #59348

Merged
wtgodbe merged 1 commit into
release/9.0from
mbuck/backport-hot-reload-fix-to-9.0
Jan 9, 2025
Merged

[release/9.0] [Blazor WASM standalone] Avoid caching index.html during development#59348
wtgodbe merged 1 commit into
release/9.0from
mbuck/backport-hot-reload-fix-to-9.0

Conversation

@MackinnonBuck

@MackinnonBuckMackinnonBuck commented Dec 5, 2024

Copy link
Copy Markdown
Member

Avoid caching index.html during development

Backport of #59340

Fixes an issue where running a Blazor WebAssembly standalone app with hot reload enabled doesn't work if the app had been previously run with hot reload disabled.

Description

Background

The Microsoft.AspNetCore.Components.WebAssembly.DevServer package provides a server for running Blazor WebAssembly standalone apps in development, and it's what gets used by default in new Blazor WebAssembly standalone projects. One of its responsibilities is serving static files, and this includes the app's index.html.

Hot reload functionality depends on an additional <script /> element being dynamically injected into the response for index.html. A development-only middleware provides this behavior.

The problem

The development server was serving index.html with a Cache-Control header that allowed the browser to cache the response. This meant that if the app was initially run with hot reload disabled, the browser would cache a version of index.html without the injected script. After enabling hot reload, the server would not detect that the cached index.html was invalid, because the file on disk had not changed. As a result, the hot reload script injection middleware would be skipped, and the cached response (without the injected script) would be used. This prevented any hot reload functionality from working.

The fix

The fix is simple: change the development server to serve index.html with a Cache-Control: no-store header, which prevents the browser from caching the response. This always gives the script injection middleware a chance to inject the hot reload script.

Fixes#59276

Customer Impact

Customers relying on the dotnet CLI to run their Blazor WebAssembly standalone app are very likely to encounter this issue. The problem can be reproduced by first running the app using dotnet run, then subsequently with dotnet watch. While less common, the bug can also be reproduced in Visual Studio by explicitly disabling hot reload, running the app, then re-enabling hot reload.

Workarounds do exist:

  • Make an arbitrary change to index.html so that the server recognizes that the file has changed
  • Clear the browser cache between runs

However, the user may not be aware of these workarounds, and being forced to manually clear the browser cache creates a frustrating development experience.

Note

Only Blazor WebAssembly standalone apps are affected. The bug does not reproduce on other types of Blazor apps (Web, Server, Hybrid).

Regression?

  • Yes
  • No

This bug has existed since .NET 6, and possibly earlier than that.

Risk

  • High
  • Medium
  • Low

The change is small and only impacts how the index.html file is served during development.

Verification

  • Manual (required)
  • Automated

Packaging changes reviewed?

  • Yes
  • No
  • N/A

@MackinnonBuckMackinnonBuck added area-blazor Includes: Blazor, Razor Components feature-blazor-wasm This issue is related to and / or impacts Blazor WebAssembly feature-hot-reload This issue is related to the Hot Reload feaature labels Dec 5, 2024
@MackinnonBuck
MackinnonBuck requested a review from a team as a code ownerDecember 5, 2024 21:56
@dotnet-policy-servicedotnet-policy-serviceBot added this to the 9.0.x milestone Dec 5, 2024
@MackinnonBuckMackinnonBuck added the ask-mode This issue / PR is a patch candidate which we will bar-check internally before patching it. label Dec 5, 2024
@MackinnonBuck

Copy link
Copy Markdown
MemberAuthor

/backport to release/8.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/8.0: https://github.com/dotnet/aspnetcore/actions/runs/12188985946

@pavelsavara

Copy link
Copy Markdown
Member

cc @maraf we have another copy of this code, right ?

@mkArtakMSFTmkArtakMSFT added Servicing-approved Shiproom has approved the issue and removed ask-mode This issue / PR is a patch candidate which we will bar-check internally before patching it. labels Dec 12, 2024
@dotnet-policy-servicedotnet-policy-serviceBot added the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Dec 19, 2024

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

Thanks @MackinnonBuck.
Why aren't there any tests for this? Is this one of the We don't have infrastructure for testing this particular area and Manual Testing has better RoI? cases?

@MackinnonBuck

MackinnonBuck commented Jan 9, 2025

Copy link
Copy Markdown
MemberAuthor

Is this one of the "We don't have infrastructure for testing this particular area and Manual Testing has better RoI" cases?

Right, we currently don't have the infrastructure to automatically test the full E2E hot reload experience, although there were some recent internal discussions around investing in this.

@halter73

Copy link
Copy Markdown
Member
  • Make an arbitrary change to index.html so that the server recognizes that the file has changed

Is this a complete workaround, or do you still need to clear the browser cache if you do this?

@MackinnonBuck

Copy link
Copy Markdown
MemberAuthor
  • Make an arbitrary change to index.html so that the server recognizes that the file has changed

Is this a complete workaround, or do you still need to clear the browser cache if you do this?

This is a complete workaround. Since the file on disk changed, the server doesn't get tricked into thinking it can return a 304. This allows the script injection middleware to run and modify the response.

This was referenced Aug 13, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-blazorIncludes: Blazor, Razor Componentsfeature-blazor-wasmThis issue is related to and / or impacts Blazor WebAssemblyfeature-hot-reloadThis issue is related to the Hot Reload feaaturepending-ci-rerunWhen assigned to a PR indicates that the CI checks should be rerunServicing-approvedShiproom has approved the issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@MackinnonBuck@pavelsavara@halter73@mkArtakMSFT@wtgodbe