Triggers, forms, and feedback

Confirm a dangerous action

Add a basic client confirmation without confusing it with server authorization or recoverability.

Deleting a task from the list is hard to undo. A confirmation step gives people a moment to reconsider before the request leaves the browser.

Add hx-confirm to the delete button on each row:

<button
  hx-delete="/tasks/42"
  hx-confirm="Permanently delete this task?"
  hx-target="closest li"
  hx-swap="delete">
  Delete
</button>

HTMX uses the browser’s confirm() dialog. Canceling prevents the request. Accepting continues the normal request cycle.

Open DevTools and test both paths. Cancel should show zero requests in the Network panel. Confirm should show exactly one DELETE /tasks/42 with HX-Request: true. On success the server can return an empty body. HTMX removes the <li> because hx-swap="delete" runs only after a 2xx status.

Confirmation is friction, not security. The delete route must still authenticate, authorize the specific task, validate CSRF protection, and behave safely when repeated. A command-line client never sees the dialog.

A realistic failure: you remove the row in JavaScript before the server responds. The row vanishes, then a 403 arrives because the task belonged to another user. Fix: never delete DOM on the client. Let HTMX remove the row only after success, or return an error and keep the row visible.

Use confirmation sparingly. If nearly every action asks “Are you sure?”, people learn to approve without reading. An archive action or short-lived undo often protects users better than a modal warning.

hx-confirm gives you the browser’s native dialog. That is fine for a quick guard rail. For richer UX, listen to htmx:confirm and show your own modal, but keep the same rule: cancel stops the request, accept lets it proceed.

Force a 500 after confirming and verify the task row stays in the list. The Network panel should show the failed DELETE while the DOM remains unchanged.

Lesson completed