Htmx support

html_of_jsx provides two packages for working with htmx:

Setup

  (libraries html_of_jsx html_of_jsx.htmx)
  (preprocess (pps html_of_jsx.ppx -htmx))

Attributes

The -htmx ppx flag enables htmx attributes on all HTML elements, scoped with the prefix hx_.

JSX.render(<div hx_boost=true />)
(* <div hx-boost="true"></div> *)

Script and extensions

The html_of_jsx.htmx library provides JSX components to load the htmx script and its extensions from a CDN.

Loading htmx

Use <Htmx /> to render a script tag that loads htmx:

<head>
  <Htmx version="2.0.4" />
</head>
(* <head><script src="https://unpkg.com/htmx.org@2.0.4"></script></head> *)

For subresource integrity, pass the integrity prop:

<Htmx
  version="2.0.4"
  integrity="sha384-HGfztofotfshcF7+8n44JQL2oJmowVChPTg48S+jvZoztPfvwD79OC/LTtG6dMp+"
/>

Loading extension scripts

Each htmx extension has its own JSX component under Htmx.Extensions that renders a <script> tag loading the extension from a CDN:

<head>
  <Htmx version="2.0.4" />
  <Htmx.Extensions.SSE version="2.2.2" />
  <Htmx.Extensions.WS version="2.2.0" />
</head>

Available extensions:

All extension components accept an optional ?version prop. Without it, the latest version is loaded from unpkg.

Full example

let make = (~name, ()) => {
  <html lang="en">
    <head>
      <title> "My App" </title>
      <Htmx version="2.0.4" />
      <Htmx.Extensions.SSE version="2.2.2" />
    </head>
    <body>
      <h1> {JSX.string("Hello, " ++ name)} </h1>
      <button hx_get="/clicked" hx_swap=`outerHTML>
        "Click me"
      </button>
      <div hx_ext="sse" sse_connect="/events" sse_swap="message">
        "Waiting for events..."
      </div>
    </body>
  </html>;
};

Extension attributes reference

htmx extensions add custom behaviors and require additional attributes. To use an extension, you need to:

  1. Load the extension script
  2. Add the hx_ext attribute to enable it
  3. Use extension-specific attributes

SSE (Server-Sent Events)

The SSE extension allows you to connect to a Server-Sent Events source and update content when events are received.

Attributes:

Example:

<div hx_ext="sse" sse_connect="/events" sse_swap="message">
  {JSX.string("Loading...")}
</div>

WebSocket

The WebSocket extension enables WebSocket communication.

Attributes:

Example:

<div hx_ext="ws" ws_connect="/chat">
  <form ws_send=true>
    <input type_="text" name="message" />
  </form>
</div>

Class-tools

The Class-tools extension allows you to add, remove, or toggle CSS classes on a schedule.

Attributes:

Example:

<div hx_ext="class-tools" classes="add highlight:1s">
  {JSX.string("This will be highlighted after 1 second")}
</div>

Preload

The Preload extension preloads linked resources to make page navigation feel instant.

Attributes:

Example:

<a hx_ext="preload" preload="mouseover" href="/page">
  {JSX.string("Hover to preload")}
</a>

Path-deps

The Path-deps extension refreshes elements when paths they depend on are modified.

Attributes:

Example:

<div hx_ext="path-deps" path_deps="/api/todos" hx_get="/todos" hx_trigger="path-deps">
  {JSX.string("Todo list")}
</div>

Loading-states

The Loading-states extension provides fine-grained control over loading indicators.

Attributes:

Example:

<button hx_post="/submit" data_loading_disable=true>
  {JSX.string("Submit")}
</button>
<div data_loading=true data_loading_delay="200ms">
  {JSX.string("Loading...")}
</div>