With all the momentum behind frontend frameworks, it’s often easy to forget that server-side rendering (SSR) is a mature approach to delivering fast and reliable user experiences. Unfortunately, one of the most significant drawbacks to frontend development is the experience can vary wildly depending on factors beyond our control, with the client doing much of the heavy lifting building the experience for the users.
Well, you’re in luck. There’s such a library, and it’s called HTMX. In this post, we’ll look through the library itself and a NuGet package I created to help ASP.NET Core developers get a seamless experience with their technology of choice.
What Is HTMX?
Let’s look at an example directly from the HTMX documentation page.
<button hx-post="/clicked" hx-trigger="click" hx-target="#parent-div" hx-swap="outerHTML"> Click Me! </button>
In the previous HTMX declaration, when you click the button, HTMX will issue a POST to our
clicked endpoint and use the response, which should be HTML, to replace the
hx-target element of
parent-div in the existing page.
- Now, any element, not just anchors and forms, can issue an HTTP request
- Now, any event, not just clicks or form submissions, can trigger requests
- Now, any HTTP verb, not just GET and POST, can be used
- Now, any element, not just the entire window, can be the target for an update by the request
The most significant difference between the single-page application approach and the HTMX approach is that your server-side technology is no longer just a JSON generator. Instead, your server can perform increasingly complex tasks to return the necessary result.
For folks working in the .NET space, they’ll likely see many similarities between HTMX and XAML-based frameworks: a declarative approach focused on what you want as an outcome, rather than an imperative process explaining each step to get the results you want.
Please take a few minutes to read the official documentation of HTMX; it’s short and descriptive and should get you thinking about all the fantastic possibilities.
HTMX and ASP.NET Core?
HX-Current-URL: The current URL as seen by the client/browser.
HX-prompt: The user response from an HTMX prompt, like a delete confirmation.
HX-Request: Will be
truewhen HTMX issues the incoming request.
There are also response headers we, as developers, can send back to our frontend to help influence different behavior:
HX-Push: pushes a new URL into the history stack
HX-Redirect: force a client-side redirect to a new location.
HX-Refresh: force an entire page refresh.
HX-Trigger: trigger a client-side event to perform some other client-side behaviors.
All these are easy enough to use with ASP.NET Core, but I’ve taken the liberty of formalizing them into a NuGet Package called HTMX. To get started, you first need to install the package into your ASP.NET Core applications.
dotnet add package Htmx
After installing the package, you can use the HTMX extension methods on the
HttpRequest class to determine if the current request occurred because of an HTMX interaction.
More commonly, you’ll use it within ASP.NET Core MVC actions or Razor Pages to perform a ternary return.
// in a Razor Page return Request.IsHtmx() ? Partial("_Form", this) : Page();
This pattern allows you to support both the regular client interaction and any subsequent HTMX requests. You can also retrieve any header values that HTMX commonly sends using the
IsHtmx overload with an
Request.IsHtmx(out var values);
Using these straightforward extension methods, you can begin to support an HTMX experience on the client-side, but what about support for generating URLs?
HTMX TagHelpers for ASP.NET Core
The heart of any great SSR is always routing, more notably the ability to generate links deterministically. ASP.NET Core is no exception, allowing you to create links to Razor pages, ASP.NET Core MVC actions, and other endpoints. In addition, generating links enables you to refactor URL paths without the need to track down hundreds of static string references.
ASP.NET Core ships with HTML tag helpers that integrate with anchor elements to help you lean on some of the concepts found in the framework.
<a asp-page="Index" /> <a asp-controller="Home" asp-action="Index" />
The previous Razor code may translate into the following HTML output.
<a href="/" /> <a href="/home/" />
ASP.Net Core route helpers are convenient, so I wanted to bring that to the folks using HTMX to enhance their ASP.NET Core application. I have ported the tag helper methods to support HTMX’s
hx-delete attributes. The first step is to install the NuGet package
dotnet add package Htmx.TagHelpers
The next step is to modify your Razor pages with the appropriate attributes.
<div hx-target="this"> <button hx-get hx-page="Index" hx-page-handler="Snippet" hx-swap="outerHtml"> Click Me (Razor Page w/ Handler) </button> </div> <div hx-target="this"> <button hx-get hx-controller="Home" hx-action="Index" hx-route-id="1"> Click Me (Controller) </button> </div> <div hx-target="this"> <button hx-post hx-route="named"> Click Me (Named) </button> </div>
Any HTML element has an
hx attribute, you can use similar tag helper attributes to generate an appropriate link. Using the helpers will reduce the number of magic strings found in your Razor files and help reduce breakage during route refactorings.
It’s that easy!
Show Me The Samples!
I’ve written some HTMX samples using ASP.NET Core as a backend for folks interested in pursuing HTMX as a client-side alternative to SPA frameworks with some everyday interactions folks may be trying to accomplish:
- Form Validation
- Updating targets when a user interacts with an element
- Polling updates for server changes
- Editable table rows
- Websocket chat client (experimental)
While the samples are impressive, they only begin to scratch the surface of what’s possible when you combine ASP.NET Core and HTMX. Check it out at my repository.
HTMX is a declarative approach to progressively enhancing your client-side experiences. By leveraging ASP.NET Core SSR frameworks and their strengths, you can reduce the complexity of many SPA frameworks in your projects. Furthermore, using the HTMX NuGet packages I’ve developed, you’ll get a very familiar experience with your current ASP.NET Core development process.
I hope you try it out and let me know your thoughts on Twitter @buhakmeh. Thank you again for reading, and I hope you found this post helpful.