Phtmx.Response (Phtmx v0.2.0)

Copy Markdown View Source

Controller helpers for driving the HTMX client from the server via HX-* response headers.

Import them wherever you build controllers — the generated scaffold does this for you in the controller/0 block of your web module:

import Phtmx.Response

Then, from an action:

def create(conn, params) do
  case save(params) do
    {:ok, _} -> conn |> put_htmx_trigger("saved") |> render(:row)
    {:error, cs} -> conn |> htmx_retarget("#form") |> render(:form, changeset: cs)
  end
end

Summary

Functions

Client-side redirect performed without a full page reload, via the HX-Location header. HTMX fetches url and swaps it in like a boosted navigation, pushing a new history entry.

Tells HTMX to perform a full client-side redirect (a real browser navigation) to url, via the HX-Redirect header.

Overrides how this response is swapped in, via the HX-Reswap header, e.g. "outerHTML", "beforeend", or "innerHTML".

Overrides which element this response is swapped into, via the HX-Retarget header. selector is a CSS selector.

Fires one or more client-side events after the response is received, via the HX-Trigger header.

Functions

htmx_location(conn, url)

@spec htmx_location(Plug.Conn.t(), String.t()) :: Plug.Conn.t()

Client-side redirect performed without a full page reload, via the HX-Location header. HTMX fetches url and swaps it in like a boosted navigation, pushing a new history entry.

htmx_redirect(conn, url)

@spec htmx_redirect(Plug.Conn.t(), String.t()) :: Plug.Conn.t()

Tells HTMX to perform a full client-side redirect (a real browser navigation) to url, via the HX-Redirect header.

Prefer this over Phoenix.Controller.redirect/2 for HTMX requests. A normal 302 response is transparently followed by HTMX and its body swapped into the target element — almost never what you want. HX-Redirect navigates the browser instead.

htmx_reswap(conn, swap)

@spec htmx_reswap(Plug.Conn.t(), String.t()) :: Plug.Conn.t()

Overrides how this response is swapped in, via the HX-Reswap header, e.g. "outerHTML", "beforeend", or "innerHTML".

htmx_retarget(conn, selector)

@spec htmx_retarget(Plug.Conn.t(), String.t()) :: Plug.Conn.t()

Overrides which element this response is swapped into, via the HX-Retarget header. selector is a CSS selector.

put_htmx_trigger(conn, event)

@spec put_htmx_trigger(Plug.Conn.t(), String.t() | [String.t()] | map()) ::
  Plug.Conn.t()

Fires one or more client-side events after the response is received, via the HX-Trigger header.

Accepts:

  • a single event name — put_htmx_trigger(conn, "cartUpdated")
  • a list of names — put_htmx_trigger(conn, ["a", "b"])
  • a map of name => detail, JSON-encoded so listeners receive the detail — put_htmx_trigger(conn, %{"cartUpdated" => %{count: 3}})