Handle browser cache for static files after deploying new code in Blazor WASM
See original GitHub issueIs there an existing issue for this?
- I have searched the existing issues
Is your feature request related to a problem? Please describe the problem.
Creating a new .NET 7 Blazor WebAssembly App project with Authentication Type Individual Accounts and ASP.NET Core Hosted gives you a index.html
that looks like this in wwwroot
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>BlazorAppIndividualAccounts</title>
<base href="/" />
<link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
<link href="css/app.css" rel="stylesheet" />
<link rel="icon" type="image/png" href="favicon.png" />
<link href="BlazorAppIndividualAccounts.Client.styles.css" rel="stylesheet" />
</head>
<body>
<div id="app">
<svg class="loading-progress">
<circle r="40%" cx="50%" cy="50%" />
<circle r="40%" cx="50%" cy="50%" />
</svg>
<div class="loading-progress-text"></div>
</div>
<div id="blazor-error-ui">
An unhandled error has occurred.
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>
<script src="_content/Microsoft.AspNetCore.Components.WebAssembly.Authentication/AuthenticationService.js"></script>
<script src="_framework/blazor.webassembly.js"></script>
</body>
</html>
We have then added a few other scripts but in this example I will keep it to one extra script called diagram-editor.js
:
<script src="js/diagram-editor.js"></script>
<script src="_content/Microsoft.AspNetCore.Components.WebAssembly.Authentication/AuthenticationService.js"></script>
<script src="_framework/blazor.webassembly.js"></script>
The scripts are then called from .NET methods.
If we update diagram-editor.js
or app.css
and then release a new version some users always hit the old values due to cache. Right now we solve it by manually incrementing a version parameter:
<script src="js/diagram-editor.js?v=1"></script>
We use the standard Etag
and Last-Modified
response headers but these are not enough.
Etag:
"1d95ec353b6b862"
Last-Modified:
Sat, 25 Mar 2023 02:41:40 GMT
We want to use cache due to performance so sending headers like below is not an option:
Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0
https://stackoverflow.com/a/2068407/3850405
Describe the solution you’d like
If I instead create a ASP.NET Core Web App
and look at _Layout.cshtml
:
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - WebApplicationRazorPage</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
<link rel="stylesheet" href="~/WebApplicationRazorPage.styles.css" asp-append-version="true" />
</head>
...
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
Here asp-append-version="true"
will load css
and js
files with a calculated hash of the file content.
Like this:
https://localhost:7188/css/site.css?v=pAGv4ietcJNk_EwsQZ5BN9-K4MuNYS2a9wl4Jw-q9D0
https://localhost:7188/js/site.js?v=4q1jwFhaPaZgr8WAUSrux6hAuh0XDg9kPS3xIVq36I0
I would like something similar for Blazor WASM that works in the .html
file and not only .cshtml
.
Additional context
No response
Issue Analytics
- State:
- Created 4 months ago
- Comments:11 (2 by maintainers)
For Blazor Webassembly there are the two flavors standalone and hosted. And you need a default document to startup your app in the browser (i.e. index.html). A standalone app in an arbitrary webserver can’t create this file on demand, so it needs to be a static file in this case. That’s fine for solutions that can life with it. But if you have a webserver that you can control, like in the hosted variant, then you can create the default document in whatever way you like. I wouldn’t judge this as bad or good practice. It’s just implementing what you need for your use case. Best practices are guides, not laws, shouldn’t be overrated. If they block you on the way to your target they can’t be good (for you).
The reason why the hosted variant creates a static index.html is probably that it is sufficient for a lot of use cases, and the same template could be used for both the standalone app and the client part of the hosted variant.
@Aeroverra I think PWA:s are great but I would prefer not dealing with a service worker simply because I want versioned scripts. PWA:s also introduce some complexity that I do not want in every case. For example:
https://github.com/dotnet/aspnetcore/issues/32522