htmx Tutorial · Making Requests · Lesson 5 of 30

AJAX Requests: hx-get, hx-post and more

The five request attributes, which HTTP method to use for what, and how the URL and values are sent.

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

One attribute per HTTP method

Attribute Method Use it to
hx-get GET read something: load a list, a page section, search results
hx-post POST create something or run an action: add a comment, log in
hx-put PUT replace a resource: save an edited record
hx-patch PATCH change part of a resource: toggle a "done" flag
hx-delete DELETE remove something

Use them the way HTTP intends. GET requests must never change data: browsers, crawlers and prefetchers may send them at any time.

POST to create, PATCH to updateTry it yourself
<ul id="todos">
  <li>Learn htmx <button hx-patch="/todos/1/toggle" hx-target="closest li" hx-swap="outerHTML">Done</button></li>
</ul>
<button hx-post="/todos" hx-target="#todos" hx-swap="beforeend">Add a todo</button>

<!-- The pretend server: on a real site this part is your backend (Python, PHP, Node, Go...) -->
<script>
  let next = 2;
  server.post("/todos", () => {
    const id = next++;
    return `<li>Todo #${id} <button hx-patch="/todos/${id}/toggle" hx-target="closest li" hx-swap="outerHTML">Done</button></li>`;
  });
  server.patch("/todos/:id/toggle", (req) => `<li><s>Todo #${req.params.id}</s> (done)</li>`);
</script>

What gets sent

  • An element sends its own value if it has one (an <input> with a name).
  • A form sends all of its fields.
  • For non-GET requests, an element inside a form also sends the enclosing form's fields.
  • GET and DELETE put the values in the URL query string (/search?q=ada); POST, PUT and PATCH send them in the request body, encoded like a normal form.
Form values in the body, GET values in the URLTry it yourself
<form hx-post="/greet" hx-target="#reply">
  <input name="name" value="Ada" required>
  <select name="lang"><option value="en">English</option><option value="es">Spanish</option></select>
  <button>Greet (POST)</button>
</form>
<input name="q" value="htmx" hx-get="/echo" hx-target="#reply" hx-trigger="click">
<small>(click the input above to send a GET)</small>
<p id="reply"></p>

<!-- The pretend server: on a real site this part is your backend (Python, PHP, Node, Go...) -->
<script>
  server.post("/greet", (req) => (req.body.lang === "es" ? "¡Hola, " : "Hello, ") + server.escape(req.body.name) + "!");
  server.get("/echo", (req) => "GET received q = " + server.escape(req.query.q));
</script>

The log shows the difference: the GET request's values are in the URL; the POST request's values are in the body (shown after the path).

Test yourself

Which attribute should a 'Delete comment' button use?

  1. hx-delete
  2. hx-get
  3. hx-post with ?delete=1
  4. hx-remove
Show answer

Answer: hx-delete

Use the HTTP method that matches the action: DELETE removes a resource.

Was this page helpful?