In server-side ASP.NET, we can do asp-append-version=true
on static assets in a .cshtml file in order to automatically append a hash of the file to the filename. But, in Blazor WebAssembly, this doesn't work, which makes sense because I have a simple index.html file that bootstraps Blazor and references static files, not a server-modified file.
So is there a good way in Blazor WebAssembly's index.html file to append a hash to the URL of a static file, similar in outcome to the old asp-append-version=true
? For example, to make <link href="css/site.css" rel="stylesheet" />
become <link href="css/site.css?v=1234abc..." rel="stylesheet" />
, and thus changes to site.css on deployment will result in all clients GETting the newly changed static file, rather than relying on cache?
I came up with a workaround for this. I have created a controller that will handle the request, read the index.html, search and replace a "{version}" placeholder and then return the content.
First step is to modify the Startup.cs:
//endpoints.MapFallbackToFile("index.html");
endpoints.MapFallbackToController("Index", "Home");
Then create a controller like this one:
public class HomeController : Controller
{
private static string _processedIndexFile;
private readonly IWebHostEnvironment _webHostEnvironment;
public HomeController(IWebHostEnvironment webHostEnvironment)
{
_webHostEnvironment = webHostEnvironment;
}
[ResponseCache(CacheProfileName = CacheProfileNames.NoCache)]
public IActionResult Index()
{
return ProcessAndReturnIndexFile();
}
private IActionResult ProcessAndReturnIndexFile()
{
if (_processedIndexFile == null)
{
IFileInfo file = _webHostEnvironment.WebRootFileProvider.GetFileInfo("index.html");
_processedIndexFile = System.IO.File.ReadAllText(file.PhysicalPath);
_processedIndexFile = _processedIndexFile.Replace("{version}", AppInfo.CompiledOn.ToString("yyyy'-'MM'-'dd'-'HH'-'mm'-'ss"));
}
return Content(_processedIndexFile, "text/html");
}
}
And finally inside the index.html file, use urls like:
<link href="css/app.min.css?v={version}" rel="stylesheet" />
This also allows you to do some other things before returning the file inside the Index method, like checking if falling back to index.html is correct for the current request:
// Check for incorrect fallback routes
if (Request.Path.Value?.Contains("api/") == true)
return NotFound();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With