Skip to content

HTMX Targets — Complete Guide with Examples

DodaTech Updated 2026-06-28 5 min read

In this tutorial, you'll learn about HTMX target selection. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.

HTMX targets determine where the server's HTML response is placed in the DOM, using CSS selectors, extended selectors like closest and next, and the special "this" keyword.

What You'll Learn

By the end of this tutorial, you'll use CSS selectors as targets, leverage extended selectors (closest, next, previous, find), target "this" for self-replacement, and override targets with response headers.

Why It Matters

Target selection controls how server responses integrate with your page. A well-chosen target updates the right content without disturbing other elements, enabling partial page updates that feel like a single-page application.

Real-World Use

A real estate listing site uses hx-target with the closest selector on each property card. Clicking "View Details" targets the specific card for expansion without affecting neighboring cards.

Where This Fits in Your Learning Path

flowchart LR
    A["HTMX Attributes"] --> B["**HTMX Targets**"]
    B --> C["HTMX Triggers"]
    C --> D["Swapping & Transitions"]
    D --> E["Advanced HTMX"]
    style B fill:#3b82f6,stroke:#2563eb,color:#fff
    style A fill:#e2e8f0,stroke:#94a3b8
    style E fill:#e2e8f0,stroke:#94a3b8

CSS Selector Targets

The most common target type. Use any valid CSS selector.

<button hx-get="/api/update" hx-target="#output">Update</button>
<div id="output">Content goes here</div>

<!-- Class selector -->
<button hx-get="/api/data" hx-target=".result-area">Show Results</button>
<div class="result-area">Results appear here</div>

<!-- Multiple elements with same class -->
<button hx-get="/api/refresh-all" hx-target=".status-item">Refresh All Statuses</button>
<div class="status-item">Status 1</div>
<div class="status-item">Status 2</div>

Expected output: The response replaces the content of the element(s) matching the CSS selector.

The "this" Target

The response replaces the triggering element itself.

<button hx-get="/api/self-destruct" hx-target="this" hx-swap="outerHTML">
  Click to Replace Myself
</button>

<!-- Useful for inline editing -->
<span hx-get="/api/user/1/edit" hx-target="this" hx-swap="outerHTML">
  Click to edit
</span>

Expected output: Clicking the button replaces it entirely with the server response. The inline span becomes editable when clicked.

The "closest" Selector

Finds the nearest ancestor matching the selector.

<div class="card">
  <h2>Card Title</h2>
  <p>Card content</p>
  <button hx-delete="/api/cards/1"
          hx-target="closest .card"
          hx-swap="outerHTML">
    Delete This Card
  </button>
</div>

<div class="card">
  <h2>Another Card</h2>
  <button hx-get="/api/cards/2/refresh"
          hx-target="closest .card"
          hx-swap="outerHTML">
    Refresh
  </button>
</div>

Expected output: Each button targets its own parent card. Clicking Delete removes only that card from the DOM.

The "next" and "previous" Selectors

Target the next or previous sibling element.

<div class="row">
  <span>Status: pending</span>
  <button hx-post="/api/approve"
          hx-target="next span"
          hx-swap="innerHTML">
    Approve
  </button>
</div>

<div class="row">
  <button hx-get="/api/previous-detail"
          hx-target="previous div">
    Show Previous
  </button>
  <div class="detail">Details here</div>
</div>

Expected output: The next span is updated with the server response. The previous div receives the content.

The "find" Selector

Targets the first child matching the selector within the triggering element.

<div class="expandable" hx-get="/api/expand" hx-target="find .content" hx-swap="innerHTML">
  <h3>Section Title</h3>
  <div class="content">Click title to expand content here</div>
</div>

Expected output: The .content div inside the clicked .expandable div receives the server response.

Overriding Targets with HX-Retarget

The server can override the target by sending the HX-Retarget response header.

// Server-side (Express example)
app.get('/api/redirect-output', (req, res) => {
  res.set('HX-Retarget', '#main-output')
  res.send('<p>This appears in #main-output instead</p>')
})

Expected output: The client-side hx-target is overridden by the server's HX-Retarget header.

Common Mistakes

1. Using closest with a class that exists in multiple ancestors

closest finds the first matching ancestor. If both parent and grandparent have the same class, the closest one (parent) is used.

2. Forgetting that next/previous targets siblings only

next and previous only find sibling elements. They do not search inside or outside the parent.

3. Using find on elements without matching children

If find doesn't locate a matching child, the response has no target. Ensure the child selector is correct.

4. Not accounting for dynamic DOM changes

If the target element is removed by a previous response, subsequent responses have nowhere to go.

5. Using ID selectors for multiple elements

IDs must be unique. Use class selectors for targeting multiple elements with the same response.

Practice Questions

  1. What does hx-target="this" do? The response replaces the element that triggered the request.

  2. How does the closest selector work? It walks up the DOM tree and finds the nearest ancestor matching the CSS selector.

  3. What is the difference between next and previous? next targets the next sibling element. previous targets the previous sibling element.

  4. How can a server override the target? By sending the HX-Retarget HTTP response header with a new CSS selector.

  5. What does the find selector do? It finds the first child of the triggering element that matches the given CSS selector.

Challenge

Build a nested comments section where each comment has reply, edit, and delete buttons. Use closest, next, and find selectors to target only the affected comment without refreshing the entire thread.

FAQ

Can I use multiple targets?

Not directly. Use HX-Retarget on the server or trigger multiple elements with the same class for simultaneous updates.

What happens if the target doesn't exist?

The response is ignored. HTMX logs a warning in the console.

Can targets be dynamic?

Yes. Use HX-Retarget header from the server or Alpine.js to change hx-target attributes dynamically.

Does the target order matter with multiple matches?

HTMX updates all matching elements. The order of updates follows DOM traversal order.

Can I target elements outside the current HTML document?

No. Targets must be within the same document.


Mini Project

Build a task list where each task item has complete, edit, and delete buttons. Use closest to target the task row, next to target the status badge, and find to target the description area within the task.

<div id="task-list">
  <div class="task" id="task-1">
    <span class="status">Pending</span>
    <span class="title">Write documentation</span>
    <button hx-post="/api/tasks/1/complete"
            hx-target="next .status"
            hx-swap="innerHTML">
      Complete
    </button>
    <button hx-get="/api/tasks/1/edit"
            hx-target="closest .task"
            hx-swap="outerHTML">
      Edit
    </button>
    <button hx-delete="/api/tasks/1"
            hx-target="closest .task"
            hx-swap="outerHTML">
      Delete
    </button>
  </div>
</div>

What's Next

Master trigger configurations:

Tutorial What You'll Learn
HTMX Triggers Advanced trigger modifiers and configurations
HTMX Swapping Swap strategies and CSS transition animations

Related topics: CSS selectors reference, DOM traversal methods.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro