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.
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.
<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 aname). - 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 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?
hx-deletehx-gethx-post with ?delete=1hx-remove
Show answer
Answer: hx-delete
Use the HTTP method that matches the action: DELETE removes a resource.