A few new tricks have shipped with the .NET 8 release, and I’d like to take this time to experiment with them. Specifically, I wanted to see if folks investing in a Blazor component library could still use the excellent HTMX library. If you want to write even less JavaScript, this blog post will be right up your alley.
This post will explore how to take a server-rendered component and give it some client-side flair without needing web
sockets or web assembly. We’ll even explore rewriting the Counter
component found in the Blazor template and building
it with HTMX in mind. Let’s go!
What is HTMX?
For folks familiar with Blazor’s interactive server mode, SignalR, aka Web sockets, the HTMX model isn’t much different.
The client communicates with the server, and the server retains stateful information. The big difference is that HTMX takes a hypermedia approach, meaning it leans on the web’s traditional request/response nature. There are no persistent connections between the client and the server. Any DOM element can initiate a request, wait for the server to process it, and then respond with appropriate HTML. Once the HTML payload is received, it is swapped into the current DOM. While the concept is simple to understand, it is powerful in practice.
What are Blazor Server-Rendered Components?
With the .NET 8 release, folks can opt-in
to multiple render modes.
The first in the list of render modes is Static
, although that’s not entirely accurate.
Static rendering implies you could compile components and assets into HTML at build time. In the case of Blazor, “ Static” rendering is more comparable to its contemporary approaches of MVC and Razor Pages. When a request to a page or component is made, the server renders the component and its component graph and then responds with HTML.
These Blazor components are all HTML, meaning they can only use HTML features and not the same interactive model you may
expect from Interactive Server
or Interactive WebAssembly
modes.
The advantage to these Components is they are lightweight payloads, fast to render, and can even be streamed via stream rendering.
Let’s Use HTMX with Blazor
Before we port our Counter
component to use HTMX, we must set up our project to make Blazor play nicely with HTMX.
The first step is to add HTMX to our App.razor
file. This is the app shell file which has our HTML structure.
We’ll also need to write a bit of JavaScript to tie into Blazor’s enhanced rendering mode.
Now, let’s set up our HtmxCounter
component. In a file, add the following Blazor component code. You’ll notice that
HTMX uses hx-*
attributes to define the behavior of DOM elements. It’s easy to pick up and can add functionality
quickly. (Not to brag, but I got this sample working on the first try. 🤩)
Next, let’s look at our endpoint holding on to state. Note that this use of state management is only for demo purposes. I recommend user-scoped state management like a database limited to a single user.
In your Blazor’s Program.cs
file, you’ll need to register the state for our component.
Next, we’ll need the endpoint to increment and render our component HTML fragment.
Finally, let’s add our component to a Blazor server-rendered page.
Let’s see what happens when we load our page.
That’s pretty cool. From a client perspective, you can’t tell which implementation uses WebSockets and which is using HTMX. That’s amazing if you ask me. The HTMX implementation will also be cheaper in the long run as it requires no more infrastructure than you currently have.
If you want to check out the sample, you can get the solution on my GitHub repository and a few more samples of using HTMX with Blazor.
Conclusion
Server-rendered components are an excellent addition to the Blazor toolbox and open up the possibility of using your component library with something as cool as HTMX. I hope you try this sample and let me know what you think.
As always, thanks for reading my blog posts. Cheers.