HTMX hx-put and hx-delete

Standard HTML forms only support GET and POST. HTMX removes that limitation. With hx-put and hx-delete, any element can send a PUT or DELETE request to the server. These two methods complete the set of CRUD operations — Create, Read, Update, Delete — that most web applications need.

The Four HTTP Methods in Context

CRUD OperationHTTP MethodHTMX AttributeExample
CreatePOSThx-postAdd a new task
ReadGEThx-getLoad a task list
UpdatePUThx-putEdit an existing task
DeleteDELETEhx-deleteRemove a task

hx-put: Updating Existing Data

Use hx-put when you want to replace an existing resource on the server. A typical use case is editing a record — such as a user's name, a blog post title, or a product price.

Basic Syntax

<form hx-put="/tasks/7" hx-target="#task-7" hx-swap="outerHTML">
  <input type="text" name="title" value="Buy groceries">
  <button type="submit">Save Changes</button>
</form>

When the user clicks "Save Changes," HTMX sends a PUT request to /tasks/7 with the new title in the request body. The server updates the record and returns updated HTML for that task. HTMX replaces the old task element with the new one.

Inline Edit Pattern

  BEFORE edit:
  ┌────────────────────────────────────┐
  │ Buy groceries         [Edit]       │
  └────────────────────────────────────┘

  After clicking [Edit]:
  ┌────────────────────────────────────┐
  │ [_Buy milk and eggs___] [Save]     │
  └────────────────────────────────────┘

  After clicking [Save] (PUT /tasks/7):
  ┌────────────────────────────────────┐
  │ Buy milk and eggs     [Edit]       │
  └────────────────────────────────────┘

This pattern requires two server routes: one GET that returns the edit form, and one PUT that saves and returns the updated display view.

Full Inline Edit Example

<!-- Display view -->
<div id="task-7">
  <span>Buy groceries</span>
  <button hx-get="/tasks/7/edit" hx-target="#task-7" hx-swap="outerHTML">
    Edit
  </button>
</div>

Server returns for GET /tasks/7/edit:

<div id="task-7">
  <form hx-put="/tasks/7" hx-target="#task-7" hx-swap="outerHTML">
    <input type="text" name="title" value="Buy groceries">
    <button type="submit">Save</button>
  </form>
</div>

Server returns for PUT /tasks/7 (after save):

<div id="task-7">
  <span>Buy milk and eggs</span>
  <button hx-get="/tasks/7/edit" hx-target="#task-7" hx-swap="outerHTML">
    Edit
  </button>
</div>

hx-delete: Removing Data

Use hx-delete when you want to remove a resource from the server. A typical use case is a delete button next to each item in a list.

Basic Syntax

<button hx-delete="/tasks/7" hx-target="#task-7" hx-swap="outerHTML">
  Delete
</button>

HTMX sends a DELETE request to /tasks/7. The server deletes the record and returns an empty response (HTTP 200 with an empty body) or a replacement element. HTMX then removes the task element from the page.

Removing an Element After Delete

The cleanest way to make an element disappear after deletion is to set hx-swap="outerHTML" and have the server return an empty string. HTMX replaces the entire element with nothing — so it vanishes.

<li id="task-7">
  Buy groceries
  <button
    hx-delete="/tasks/7"
    hx-target="#task-7"
    hx-swap="outerHTML">
    ✕ Delete
  </button>
</li>

Server response (empty body, status 200):

(empty string)
  Diagram:

  LIST BEFORE DELETE:
  • Buy groceries  [✕ Delete]
  • Call the bank  [✕ Delete]
  • Return package [✕ Delete]

  User clicks [✕ Delete] on "Buy groceries"
          |
          v
  DELETE /tasks/7  ----->  Server deletes record, returns ""
          |
          v
  HTMX replaces #task-7 with ""  (element disappears)
          |
          v
  LIST AFTER DELETE:
  • Call the bank  [✕ Delete]
  • Return package [✕ Delete]

Adding a Confirmation Step

Deletions are irreversible. You can add a built-in confirmation dialog with the hx-confirm attribute:

<button
  hx-delete="/tasks/7"
  hx-target="#task-7"
  hx-swap="outerHTML"
  hx-confirm="Are you sure you want to delete this task?">
  Delete
</button>

HTMX shows a native browser confirm dialog before sending the request. If the user clicks Cancel, nothing happens. The Confirm Dialogs topic covers custom confirmation UIs in more detail.

Server-Side Handling

Flask (Python) — PUT and DELETE

@app.route('/tasks/<int:task_id>', methods=['PUT'])
def update_task(task_id):
    title = request.form.get('title')
    # update in database...
    return f'''
      <div id="task-{task_id}">
        <span>{title}</span>
        <button hx-get="/tasks/{task_id}/edit" ...>Edit</button>
      </div>
    '''

@app.route('/tasks/<int:task_id>', methods=['DELETE'])
def delete_task(task_id):
    # delete from database...
    return '', 200

Key Takeaway

Use hx-put for updating existing records and hx-delete for removing them. Both work on any HTML element. Combine them with hx-target and hx-swap="outerHTML" to update or erase specific elements on the page. Pair hx-delete with hx-confirm to protect users from accidental data loss. Together, these four HTMX attributes give you complete CRUD capability with nothing but HTML attributes.

Leave a Comment

Your email address will not be published. Required fields are marked *