DEV Community

Daniel J. Summers
Daniel J. Summers

Posted on • Originally published at blog.bitbadger.solutions on

Introducing Giraffe.Htmx

Giraffe is a library that sits atop ASP.NET Core and allows developers to build web applications in a functional style; dotnet new giraffe is literally my starting point when I begin a new web application project. (Rather than write three more sentences filled with effusive praise, I’ll just leave it at that; it’s great.) It also provides a view engine (that builds upon Suave‘s “experimental” view engine) which uses an F# DSL to define HTML in a strongly-typed way. It has been incredibly efficient for a while, but with .NET’s work over the past two releases at improving performance, and Giraffe’s adoption of those techniques, it is lightning fast.

htmx is a library that brings interactivity to HTML through the use of attributes and HTTP headers. Whereas projects like Vue, Angular, and React prescribe completely different programming paradigms than traditional web development, htmx provides partial-page-swapping and progressive enhancement within straight HTML. This brings a lot of the benefits of the SPA architecture to vanilla HTML, without requiring a completely different paradigm than the one we have used on the web for 30 years. In practice, this greatly reduces the complexity required to produce an interactive web application.

The Giraffe.Htmx project provides a bridge between these two libraries. The project consists of two different NuGut packages.

  • Giraffe.Htmx provides extensions to Giraffe (and its exposure of ASP.NET Core’s HttpContext) that expose the request headers which htmx uses, and provides Giraffe-style HttpHandlers to set htmx’s recognized response headers. The request headers are exposed as Options, and if present, are converted to the expected type. Response headers can be set in a similar way (i.e., passing true instead of "true" for a boolean header).
let myHandler : HttpHander =
fun next ctx ->
match ctx.Request.HxPrompt with
 | Some prompt -> ... // do something with the text the user provided
 | None -> ... // the user provided no text (likely was not even prompted)
 ...

Enter fullscreen mode Exit fullscreen mode
  • Giraffe.ViewEngine.Htmx extends Giraffe’s view engine with attribute functions (ex. _hxBoost equates to hx-boost="true") to generate HTML with htmx attributes. As with the headers, the values for each attribute are expected in their strongly-typed form, and the library handles the necessary string conversion. For attributes that have a defined set of values, there are also modules that provide those values; the example below demonstrates both the attributes and the HxTrigger module.
let autoLoad =
 div [\_hxGet "/this/endpoint"; \_hxTrigger HxTrigger.Load] [str "Loading..."] 

Enter fullscreen mode Exit fullscreen mode

Head over to the project site for NuGet links and more examples!

p.s. As of this publishing (on dev.to), the current version of Giraffe.Htmx is v0.9.3 (includes the HX-Retarget header introduced in htmx v1.6.1), and Giraffe.ViewEngine.Htmx is v0.9.2. Both are release-ready, and will go 1.0 in early 2022.

Latest comments (0)