How to use .NET 9 to ensure users always get the latest version of your stylesheets

November 11, 2024 · 2 minute read · Tags: aspnet | blazor | net9

Ever made a change to your Blazor app’s CSS only to find, when you publish your app, it seems to be stuck using the old styles?

Modern browsers love to cache static assets like stylesheets.

It speeds up performance and saves re-fetching the same thing multiple times from the server.

The problem comes when you make changes to the stylesheet and push out a new version.

Unless you change the filename of the stylesheet, the browser sees that your site is requesting a file it’s already cached and diligently serves the contents from the cache.

One low-tech way to manage is to change the filename every time your publish your app.

One common technique is to append a “fake” querystring value to the filename.

<head>
	<link href="css/app.css?version=2"  rel="stylesheet"/>    
</head>

This works, but requires you to manually tweak this version for every deploy (easily forgotten in the rush to get a new deployment out the door).

It also falls apart when you have a team working on the app, with multiple developers trying to make sure their version is picked up.

.NET 9 solves this problem with its new and improved static asset handling.

Here’s how it works.

First you need to configure your app to use the new static file handling middleware.

Program.cs

// remove the old call to use static assets
// app.UseStaticFiles();

// add this
app.MapStaticAssets();

By itself this won’t do much so the next step is to update your stylesheet references, typically in App.razor.

App.razor

<head>
	<!-- <link rel="stylesheet" href="app.css" /> -->
	<link rel="stylesheet" href="@Assets["app.css"]"/>
</head>

Note how we’re using the new @Assets directive.

Under the hood Blazor will render this link using a unique filename, based on the contents of the file.

Here’s an example of how it looks in the browser.

<head>
	<link rel="stylesheet" href="app.khy4lop6wu.css" />
</head>

With this your users will always get the latest version of your styles, and you can stop wrestling with your teammates over made-up version number query string values! 😜

– Jon

Next up

.NET 9 improves JavaScript module importing for Blazor
.NET 9 ensures your users always get the latest version of your JS modules
Preventing double clicks in Blazor components
Guard against duplicate events in your Blazor app
Avoiding interactivity with Blazor?
Sometimes a little HTML and CSS is all you need