Htmx with Asp.Net Core (English)

Htmx with Asp.Net Core

Comments

NOTE: Apart from English (and even then it's questionable, I'm Scottish). These are machine translated in languages I don't read. If they're terrible please contact me.
You can see how this translation was done in this article.

Thursday, 01 August 2024

//

3 minute read

Introduction

Using HTMX with ASP.NET Core is a great way to build dynamic web applications with minimal JavaScript. HTMX allows you to update parts of your page without a full page reload, making your application feel more responsive and interactive.

It's what I used to call 'hybrid' web design where you render the page fully using server-side code and then use HTMX to update parts of the page dynamically.

In this article, I'll show you how to get started with HTMX in an ASP.NET Core application.

Prerequisites

HTMX - Htmx is a JavaScript package the easist way to include it in your project is to use a CDN. (See here )

<script src="https://unpkg.com/[email protected]" integrity="sha384-QWGpdj554B4ETpJJC9z+ZHJcA/i59TyjxEPXiiUgN2WmTyV5OEZWCD6gQhgkdpB/" crossorigin="anonymous"></script>

You can of course also download a copy and include it 'manually' (or use LibMan or npm).

ASP.NET Bits

I also recommend installing the Htmx Tag Helper from here

These are both from the wonderful Khalid Abuhakmeh

dotnet add package Htmx.TagHelpers

And the Htmx Nuget package from here

 dotnet add package Htmx

The tag helper lets you do this:

    <a hx-controller="Blog" hx-action="Show" hx-push-url="true" hx-get hx-target="#contentcontainer" hx-route-slug="@Model.Slug"
        class="block font-body text-lg font-semibold text-primary transition-colors hover:text-green dark:text-white dark:hover:text-secondary">@Model.Title</a>

Alternative approach.

NOTE: This approach has one major drawback; it doesn't produce an href for the post link. This is a problem for SEO and accessibility. It also means these links will fail if HTMX for some reason doesn't load (CDNs DO go down).

An alternative approach is to use the hx-boost="true" attribute and normal asp.net core tag helpers. See here for more info on hx-boost (though the docs are a bit sparse). This will output a normal href but will be intercepted by HTMX and the content loaded dynamically.

So as follows:

 <a asp-controller="Blog" asp-action="Show" hx-boost="true"  hx-target="#contentcontainer" asp-route-slug="@Model.Slug"
       class="block font-body text-lg font-semibold text-primary transition-colors hover:text-green dark:text-white dark:hover:text-secondary">@Model.Title</a>

Partials

HTMX works well with partial views. You can use HTMX to load a partial view into a container on your page. This is great for loading parts of your page dynamically without a full page reload.

In this app we have a container in the Layout.cshtml file that we want to load a partial view into.

    <div class="container mx-auto" id="contentcontainer">
   @RenderBody()

    </div>

Normally it renders the server side content but using the HTMX tag helper about you can see we target hx-target="#contentcontainer" which will load the partial view into the container.

In our project we have the BlogView partial view that we want to load into the container.

img.png

Then in the Blog Controller we have

    [Route("{slug}")]
    [OutputCache(Duration = 3600)]
    public IActionResult Show(string slug)
    {
       var post =  blogService.GetPost(slug);
       if(Request.IsHtmx())
       {
              return PartialView("_PostPartial", post);
       }
       return View("Post", post);
    }

You can see here we have the HTMX Request.IsHtmx() method, this will return true if the request is an HTMX request. If it is we return the partial view, if not we return the full view.

Using this we can ensure that we also support direct querying with little real effort.

In this case our full view refers to this partial:

@model Mostlylucid.Models.Blog.BlogPostViewModel

@{
ViewBag.Title = "title";
Layout = "_Layout";
}
<partial name="_PostPartial" model="Model"/>

And so we now have a super simple way to load partial views into our page using HTMX.

logo

©2024 Scott Galloway