htmx Tutorial · Common Patterns · Lesson 19 of 30

Delete a Row

Delete items from a table with confirmation and a fade-out, using one hx-confirm for the whole table.

Create a free account to save this page, take notes and track your progress. Sign in

The pattern

  • Put hx-confirm and hx-target="closest tr" on the <tbody>: every delete button inside inherits them.
  • Each button only needs hx-delete="/contacts/<id>".
  • hx-swap="outerHTML swap:400ms" and a CSS transition fade the row out.
  • The server deletes the record and returns an empty 200 response, so the row is replaced by nothing.
Delete with confirmation and a fadeTry it yourself
<style>tr.htmx-swapping td { opacity: 0; transition: opacity 400ms; }</style>
<table>
  <thead><tr><th>Name</th><th></th></tr></thead>
  <tbody hx-confirm="Delete this contact?" hx-target="closest tr" hx-swap="outerHTML swap:400ms">
    <tr><td>Ada</td><td><button hx-delete="/contacts/1">Delete</button></td></tr>
    <tr><td>Grace</td><td><button hx-delete="/contacts/2">Delete</button></td></tr>
    <tr><td>Linus</td><td><button hx-delete="/contacts/3">Delete</button></td></tr>
  </tbody>
</table>

<!-- The pretend server: on a real site this part is your backend (Python, PHP, Node, Go...) -->
<script>
  server.delete("/contacts/:id", () => "");   // 200 with an empty body: the row is replaced by nothing
</script>

Don't use status 204 for this: htmx doesn't swap a 204 response, so the row would stay on the page.

Test yourself

Your delete endpoint returns 204 No Content, and the row doesn't disappear. Why?

  1. htmx doesn't swap 204 responses; return 200 with an empty body
  2. DELETE requests can't change the page
  3. hx-target must be the button
  4. 204 responses are cached
Show answer

Answer: htmx doesn't swap 204 responses; return 200 with an empty body

By default, 204 means 'nothing to swap'. An empty 200 replaces the target with nothing.

Was this page helpful?