How I use HTMX with Go

gnabgib1 pts0 comments

How I use HTMX with Go– Alex Edwards

Not sure how to structure your Go web application?

My new book guides you through the start-to-finish build of a real world web application in Go — covering topics like how to structure your code, manage dependencies, create dynamic database-driven pages, and how to authenticate and authorize users securely.

Mid-year sale: 30% off until the end of July!

Take a look!

When I want to add sprinkles of interactivity to a web application, I'm a big fan of using HTMX. I like that it makes it easy to give interactions a smooth app-like feel, I like that it minimizes the amount of JavaScript that I have to write, and I like that it allows me to keep the consistency and safety of server-side HTML rendering with Go's html/template package.

In this post I'm going to run through how I typically use HTMX in conjunction with Go. Although I'm going to talk a bit about how HTMX works, the main focus is going to be on the Go side of things. Specifically:

The patterns I use for structuring HTML templates and sending back partial and full-page HTML responses to HTMX

Managing redirects and errors when using HTMX

The standard HTMX configuration settings that I use, and why

To illustrate these things, we'll run through the build of a small application that ultimately implements a filter on a list of users like this:

Note: If you're not already familiar with the basics of using HTMX, I recommend skimming through the HTMX docs before continuing.

Also note: A lot of the patterns for working with HTML templates should also be a good fit for other HTML-over-the-wire tools like Unpoly and Hotwire too, if you prefer to use those.

Project setup

If you'd like to follow along, go ahead and run the following commands to create a skeleton structure for the project:

$ go mod init example.com/htmx<br>$ mkdir -p assets/static/css assets/static/img assets/static/js assets/html/partials assets/html/pages cmd/web<br>$ touch assets/efs.go assets/html/base.tmpl assets/html/partials/images.tmpl assets/html/pages/home.tmpl cmd/web/main.go cmd/web/handlers.go cmd/web/html.go

That should give you a file tree which looks like this:

├── assets<br>│   ├── efs.go<br>│   ├── html<br>│   │   ├── base.tmpl<br>│   │   ├── pages<br>│   │   │   └── home.tmpl<br>│   │   └── partials<br>│   │   └── images.tmpl<br>│   └── static<br>│   ├── css<br>│   ├── img<br>│   └── js<br>├── cmd<br>│   └── web<br>│   ├── handlers.go<br>│   ├── html.go<br>│   └── main.go<br>└── go.mod

Installing HTMX

There are a few different ways to install HTMX, and you could load it from a CDN or install it using NPM, but I almost always download a copy and serve it as a static file from my web application. It's simple and avoids the downsides of using a CDN.

For the purpose of this demo project, we'll also download Bamboo (a classless CSS framework) and an image of a gopher from github.com/egonelbre/gophers. Go ahead and run the following commands to download all three things into the assets/static folder:

$ wget -P assets/static/js https://cdn.jsdelivr.net/npm/[email protected]/dist/htmx.min.js<br>$ wget -P assets/static/css https://cdn.jsdelivr.net/npm/[email protected]/dist/bamboo.min.css<br>$ wget -O assets/static/img/gopher.png https://raw.githubusercontent.com/egonelbre/gophers/refs/heads/master/sketch/misc/standing-left.png

The contents of assets/static should now look like this:

assets/static<br>├── css<br>│   └── bamboo.min.css<br>├── img<br>│   └── gopher.png<br>└── js<br>└── htmx.min.js

The HTML templates

OK, now that the project skeleton and our static assets are in place, let's get to the main thrust of this post and talk about HTML templates.

My starting point in almost all projects is an assets/html directory which has a folder structure like this:

assets/html<br>├── base.tmpl<br>├── pages<br>│ └── home.tmpl<br>└── partials<br>└── images.tmpl

Under this structure:

The assets/html/base.tmpl file contains the common HTML 'layout' markup for all web pages.

The files in the assets/html/pages directory contain the page-specific content for individual web pages.

The files in the assets/html/partials directory contain reusable chunks of HTML markup that can be used in different places.

If you're following along, go ahead and add the following markup to the base.tmpl file:

File: assets/html/base.tmpl<br>{{define "base"}}

{{template "page:title" .}}

Example website

{{template "page:content" .}}

{{end}}

There are a few things to point out about this:

In the section we import the Bamboo CSS file and the HTMX JavaScript file. Note that when importing HTMX we use the defer attribute. This means that HTMX will be fetched by the browser in parallel as it is parsing the web page HTML, but the script won't be executed until the HTML is fully parsed and the DOM is built. There's an excellent blog post which describes how defer works and why it's the right choice here.

When writing HTML templates, I like to give all of my templates explicit names by surrounding the markup in {{define}}...{{end}} actions — even if...

html assets htmx like static tmpl

Related Articles