HTMX htmx.ajax API

Every HTMX request you have learned so far starts from an HTML attribute — a button you click or a div that loads on reveal. But sometimes you need to fire an HTMX request entirely from JavaScript, without any element interaction. The htmx.ajax() function is the tool for that. It gives JavaScript code the ability to send HTMX-style requests and place the response anywhere on the page.

When to Use htmx.ajax

  • A WebSocket message arrives and you want to reload a panel.
  • A JavaScript timer fires and you want to refresh a widget.
  • A drag-and-drop action completes and you want to save the new order.
  • A third-party callback runs (payment confirmed, OAuth authorized) and you want to update the UI.
  • A file drop lands and you want to trigger an upload.

In all of these cases, there is no HTML element for the user to click. The request starts from code, not from the DOM.

Basic Syntax

htmx.ajax(METHOD, URL, TARGET_OR_OPTIONS)
ParameterTypeDescription
METHODstring'GET', 'POST', 'PUT', 'DELETE'
URLstringThe endpoint to send the request to
TARGET_OR_OPTIONSstring or objectCSS selector string, or an options object

Simple GET: Load Content Into a Target

// Fetch a partial and place it into #dashboard-widget
htmx.ajax('GET', '/widgets/revenue', '#dashboard-widget');

This is the JavaScript equivalent of:

<div hx-get="/widgets/revenue" hx-trigger="load" hx-target="#dashboard-widget"></div>

Using the Options Object

When you need more control — custom swap strategy, request body, or source element — use the options object:

htmx.ajax('POST', '/comments', {
    target: '#comment-list',
    swap: 'beforeend',
    values: {
        author: 'Alice',
        body: 'Great post!'
    }
});

Options Reference

OptionTypeDefaultDescription
targetstring / Elementdocument.bodyCSS selector or element to update
swapstringinnerHTMLSwap strategy (same values as hx-swap)
valuesobject / FormDataData to send in the request body
sourcestring / ElementElement to use as the request source (for headers)
headersobjectCustom headers to include
handlerfunctionCustom response handler function

Real Example: WebSocket Message Triggers Reload

<div id="order-status">
  Status: Pending
</div>

<script>
const socket = new WebSocket('wss://example.com/orders/42');

socket.addEventListener('message', function(event) {
    const data = JSON.parse(event.data);

    if (data.type === 'order_updated') {
        // WebSocket says the order changed — fetch fresh HTML from server
        htmx.ajax('GET', '/orders/42/status', {
            target: '#order-status',
            swap: 'innerHTML'
        });
    }
});
</script>
  Flow:

  Server sends WebSocket message: { type: "order_updated" }
           |
           v
  JavaScript receives message
           |
           v
  htmx.ajax fires GET /orders/42/status
           |
           v
  Server returns: <p>Status: Shipped</p>
           |
           v
  #order-status updates from "Pending" to "Shipped"
  — no button click, no page reload

Sending a FormData Object

When uploading a file or sending complex form data from JavaScript, pass a FormData object as the values option:

const dropZone = document.getElementById('drop-zone');

dropZone.addEventListener('drop', function(e) {
    e.preventDefault();
    const formData = new FormData();
    formData.append('file', e.dataTransfer.files[0]);

    htmx.ajax('POST', '/upload', {
        target: '#upload-result',
        swap: 'innerHTML',
        values: formData
    });
});

Handling the Response in JavaScript

htmx.ajax() returns a Promise. You can await it and inspect the result:

async function refreshPanel() {
    try {
        const result = await htmx.ajax('GET', '/panel', '#panel-container');
        console.log('Panel updated successfully');
    } catch (error) {
        console.error('Panel update failed:', error);
    }
}

Using a Custom Handler

A custom handler function receives the response before HTMX swaps it in. You can inspect or transform the response HTML:

htmx.ajax('GET', '/data', {
    target: '#output',
    handler: function(element, response) {
        // element = the target element
        // response.responseText = raw HTML from server
        if (response.status === 200) {
            element.innerHTML = response.responseText;
        } else {
            element.innerHTML = '<p>Failed to load data.</p>';
        }
    }
});

Key Takeaway

The htmx.ajax() function extends HTMX into JavaScript-driven scenarios. Use it when no HTML element triggers the request — when a timer fires, a WebSocket message arrives, a drag-and-drop action completes, or a third-party callback runs. Pass a CSS selector as the third argument for simple requests, or an options object for full control over target, swap strategy, request body, and headers. It returns a Promise, so you can chain logic after the response arrives.

Leave a Comment

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