Triggers, forms, and feedback

Show request progress

Reveal a meaningful status while work is in flight and hide it again when the request ends.

When a request takes more than a blink, people need to know something is happening. HTMX adds htmx-request to the trigger and to any element you point at with hx-indicator.

Wire a status element to a button:

<button hx-post="/tasks/42/complete" hx-indicator="#save-status">
  Complete
</button>

<span id="save-status" class="htmx-indicator" role="status">
  Saving…
</span>

While the request is active, HTMX adds htmx-request to #save-status. Built-in indicator styles reveal .htmx-indicator elements during that class. You can replace the default CSS with your own presentation.

Use text that explains the operation. A spinner alone does not tell someone whether the page is loading, saving, deleting, or stuck. “Saving…” and “Deleting…” are better than a generic spinner.

An indicator covers only the in-flight state. On success, the returned HTML should show the new task state, such as “Completed” on the row. On failure, replace “Saving…” with a clear error and retry path. Do not simply hide the indicator and leave the old state.

You can point hx-indicator at a parent region if several controls share one status line. Just keep the message specific enough to match the action that started the request.

You can also put htmx-indicator on the trigger itself. HTMX will treat that element as its own indicator. That works for a button that swaps its label to “Saving…” via CSS while htmx-request is present.

Multiple concurrent requests need separate indicators. One global spinner cannot explain three different operations running at once.

Throttle the connection in DevTools so the indicator stays visible long enough to inspect. Confirm it appears only for the related request and that the control is not left in a busy state after an error.

Lesson completed