I have been using htmx and django for several personal project dashboards. Instead of doing a full page load, I wanted a way to refresh individual ‘widgets’ and I think I came up with a simple way to handle it.
Intial Load
For the initial load, I have a simple section that just loads a specific widget
<section hx-get="{% url 'development:htmx-forgejo' %}" hx-trigger="load">
<p>Forgejo</p>
</section>
Given a django URL, I have htmx do a fetch on page load.
Reload
For reloading, this is what I ended up with.
<table
id="{{request.path|slugify}}"
class="table table-sm table-bordered table-hover"
>
<thead class="table-dark">
<tr>
<th>Forgejo ({{forgejo_list|length}})</th>
<th>Title</th>
<th>Repo</th>
<th>Labels</th>
<th>Due Date</th>
<th>Remaining</th>
<th>
<details>
<summary>Debug</summary>
<button
hx-get="{{request.path}}"
hx-target="#{{request.path|slugify}}"
hx-swap="outerHTML"
class="badge text-bg-info"
>
Reload
</button>
<a
class="badge text-bg-warning"
target="_blank"
href="{{request.path}}"
>New Tab</a
>
</details>
</th>
</tr>
</thead>
</table>
We first need a button that we can click to reload
<button>Reload</button>
Since we want to reload the page itself, we can easily use request.path to configure hx-get
<button hx-get="{{request.path}}">Reload</button>
We want to replace a specific target, so we can build a target based on the path, though we escape in case of weird symbols. In my case, I’m replacing a table
<table id="{{request.path|slugify}}"></table>
<button hx-get="{{request.path}}" hx-target="#{{request.path|slugify}}">
Reload
</button>
Lastly, we want to make sure to replace the whole table to avoid weird nesting.
<table id="{{request.path|slugify}}"></table>
<button
hx-get="{{request.path}}"
hx-target="#{{request.path|slugify}}"
hx-swap="outerHTML"
>
Reload
</button>