How to Build Simple Web Polling with HTMX (with Examples)
Date: 2024-07-31 | create | tech | htmx |
I recently built a side project that heavily relies on HTMX polling. In this post we'll dive into how it works, examples of how to implement polling with HTMX, and ideas for how you might use this in your own projects.
HTMX Project Overview
I like building side projects with HTMX so naturally I built my latest side project (1000 checkboxes) with it. We'll start with an overview of how it works to give context for how HTMX polling is used.
How 1000 checkboxes works:
- Loads a page of 1000 checkboxes
- You check boxes, it syncs to server
- Pages poll to get updated checkboxes
Under the hood it uses HTMX polling to get the latest checkbox state every few seconds (and minimize the amount of HTML we send on each poll).
Learn more:
- Try it out: https://1000checkboxes.xyz/
- 1000 checkboxes - Tech stack, design decisions, and challenges of using HTMX
- Full project source code is available to HAMINIONs Members
Simple HTMX Polling Example
Now that we know how the project works we can dive into how it uses HTMX for polling.
The page is served as an MPA with the checkbox grid being an Interactive Island. An Interactive Island is essentially a ~self-contained component that can re-render itself when it needs to. I like the Interactive Island paradigm for HTMX componentization because I find it allows you to leverage the power of HTMX while minimizing extra complexity.
To setup polling with HTMX we are going to use the hx-trigger
attribute to configure when our component decides to refresh itself. Here we set it to trigger on load with a delay effectively creating a polling scenario where it refreshes itself on each delay.
This component:
- Gives itself an ID:
CheckboxGrid
- Targets itself with
hx-target="#CheckboxGrid"
- Specifies what url to hit to reload itself:
hx-get="/"
- Sets a trigger to reload itself on a 5s delay after loading:
hx-trigger="load delay:5s"
- Has all of the checkboxes inside of it
The backend:
- Sees that the target is
CheckboxGrid
- Re-renders the full HTMX component with newly-updated checkboxes
- Returns the whole component
HTML code:
<div id="CheckboxGrid" hx-get="/" hx-target="#CheckboxGrid" hx-trigger="load delay:5s" class="grid place-items-center">
<input type="checkbox" name="0" checked="" hx-post="/update-checkbox/0" hx-trigger="change" hx-swap="none" class="checkbox checkbox-md">
<input type="checkbox" name="0" checked="" hx-post="/update-checkbox/1" hx-trigger="change" hx-swap="none" class="checkbox checkbox-md">
<!-- More checkboxes here -->
</div>
You can see this code in action at https://1000checkboxes.xyz/
How to use HTMX Polling in your own Projects
Okay so we've gone over a simple example of web polling with HTMX but I wanted to provide some ideas for how you might use this in your own projects.
- Refreshing on a timer - In this project I have a naive endless poll because I know I want the page to pull the latest info regularly forever. This is useful in some scenarios but often is wasteful because you're continuously refreshing even if the underlying data has not changed.
- Poll til ready - A more common scenario is to poll a given resource until it is ready. This is often used when a resource takes awhile to reach a terminal state like requires background processing or is awaiting some other async task. In this case you might use HTMX to create a poll while the resource is not yet ready and then when it reaches a terminal state (whether success or fail) return an element without a poll.
- Polling with backoff - In higher scale scenarios where we may have lots of pollers at once we may want to be more cautious about how we do polling. With lots of parallel pollers we risk overrunning our systems with the load of these polls. This is why many retry systems implement backoffs - lowering the load each poller puts on the system by making it poll less frequently over time. Implementing this in HTMX requires a few extra steps like tracking retries / current backoff but since it always returns server-side rendered markdown it's definitely possible to configure frontend pollers in this way increasing delays from 5s -> 10s -> 30s etc.
Next
I've now been playing with HTMX for ~6 months and have been very happy with it for building my side projects. It feels like a Simple Scalable System for building simple webapps as MPAs and sprinkling in some dynamism when useful. Hopefully this post helps you along with your next HTMX project.
Q: How are you using HTMX in your projects? What's been the hardest thing to do with it?
If you liked this post you might also like:
Want more like this?
The best / easiest way to support my work is by subscribing for future updates and sharing with your network.