Dynamic Updates

Fetching new content from the server incrementally

Concepts

What HTMX does

Including HTMX

Loading a detail panel on demand

HTMX and Alpine.js together

Check for Understanding

What is the difference between a full page reload and an HTMX partial update from the user's perspective? From the server's perspective?

From the user's perspective: a full reload navigates away from the current page and reloads everything, causing a visible flash and resetting scroll position. A partial update replaces only a section of the page, which is faster and less disruptive. From the server's perspective: a full reload receives a regular browser request and must return a complete HTML page. An HTMX request includes an HX-Request: true header; the server can detect this and return only the relevant fragment.

What does hx-target="#detail-panel" tell HTMX to do?

It tells HTMX to put the response content into the element with id="detail-panel", using whatever swap strategy hx-swap specifies (the default is to replace the inner HTML). Without hx-target, HTMX replaces the content of the element that triggered the request.

How does the server know a request came from HTMX rather than a regular browser navigation?

HTMX adds an HX-Request: true HTTP header to every request it makes. The server can inspect this header to decide whether to return a full page or just a fragment. In Litestar, you can read request headers in a handler; some frameworks also provide middleware that detects this header automatically.

If Alpine.js manages local state and HTMX fetches server content, which tool would you use for each of these: (a) a dropdown that shows/hides options, (b) loading updated search results from the server?

(a) Alpine.js: showing and hiding a dropdown does not require a server round-trip; it is purely local state (open = true/false) that controls visibility. (b) HTMX: fetching updated search results requires sending the query to the server and getting back fresh data; HTMX triggers the request and swaps the result into the page.

Exercises

Inline delete

Add an HTMX-powered delete button to each table row. When clicked, it should send a DELETE request to the server. The server should delete the record and return an empty response; HTMX should remove the row from the page without a full reload. Test that a refresh does not re-add the deleted row.

Search-as-you-type

Add hx-trigger="keyup delay:300ms" to the search input so HTMX sends a new request 300 milliseconds after the user stops typing. The server should return only the table body fragment. Explain why the 300ms delay is there.

Loading indicators

Add a spinner (a CSS animation or a simple text message like "Loading...") that appears while an HTMX request is in flight and disappears when the response arrives. Use the hx-indicator attribute to connect the spinner to the request. Test it by adding an artificial delay to the server.

Compare approaches

Implement loading a detail panel for a row in two ways: (1) as a regular link that navigates to a new page, and (2) using HTMX. Which is faster? Which preserves scroll position? Which is more code? Which would you choose for this application and why?