Skip to content

HTMX Support

Helpers for building HTMX-powered web applications with partial page updates.

HtmxHeaders

HtmxHeaders dataclass

Parsed HTMX request headers.

Injected into handlers that declare an HtmxHeaders parameter. Provides typed access to all standard HTMX request headers.

Attributes:

Name Type Description
is_htmx bool

True if the request was made by HTMX (HX-Request header present).

boosted bool

True if the request came from an hx-boost element.

target str | None

The id of the target element (HX-Target header).

trigger str | None

The id of the element that triggered the request (HX-Trigger header).

trigger_name str | None

The name of the trigger element (HX-Trigger-Name header).

current_url str | None

The current browser URL (HX-Current-URL header).

prompt str | None

The user response to an hx-prompt (HX-Prompt header).

Source code in src/agenticapi/interface/htmx.py
@dataclass(frozen=True, slots=True)
class HtmxHeaders:
    """Parsed HTMX request headers.

    Injected into handlers that declare an ``HtmxHeaders`` parameter.
    Provides typed access to all standard HTMX request headers.

    Attributes:
        is_htmx: True if the request was made by HTMX (HX-Request header present).
        boosted: True if the request came from an hx-boost element.
        target: The id of the target element (HX-Target header).
        trigger: The id of the element that triggered the request (HX-Trigger header).
        trigger_name: The name of the trigger element (HX-Trigger-Name header).
        current_url: The current browser URL (HX-Current-URL header).
        prompt: The user response to an hx-prompt (HX-Prompt header).
    """

    is_htmx: bool = False
    boosted: bool = False
    target: str | None = None
    trigger: str | None = None
    trigger_name: str | None = None
    current_url: str | None = None
    prompt: str | None = None

    @classmethod
    def from_scope(cls, scope: dict[str, Any]) -> HtmxHeaders:
        """Extract HTMX headers from an ASGI scope.

        Args:
            scope: The ASGI scope dict containing request headers.

        Returns:
            Parsed HtmxHeaders instance.
        """
        headers: dict[str, str] = {}
        for key, value in scope.get("headers", []):
            headers[key.decode("latin-1").lower()] = value.decode("latin-1")

        return cls(
            is_htmx=headers.get("hx-request", "").lower() == "true",
            boosted=headers.get("hx-boosted", "").lower() == "true",
            target=headers.get("hx-target"),
            trigger=headers.get("hx-trigger"),
            trigger_name=headers.get("hx-trigger-name"),
            current_url=headers.get("hx-current-url"),
            prompt=headers.get("hx-prompt"),
        )

from_scope classmethod

from_scope(scope: dict[str, Any]) -> HtmxHeaders

Extract HTMX headers from an ASGI scope.

Parameters:

Name Type Description Default
scope dict[str, Any]

The ASGI scope dict containing request headers.

required

Returns:

Type Description
HtmxHeaders

Parsed HtmxHeaders instance.

Source code in src/agenticapi/interface/htmx.py
@classmethod
def from_scope(cls, scope: dict[str, Any]) -> HtmxHeaders:
    """Extract HTMX headers from an ASGI scope.

    Args:
        scope: The ASGI scope dict containing request headers.

    Returns:
        Parsed HtmxHeaders instance.
    """
    headers: dict[str, str] = {}
    for key, value in scope.get("headers", []):
        headers[key.decode("latin-1").lower()] = value.decode("latin-1")

    return cls(
        is_htmx=headers.get("hx-request", "").lower() == "true",
        boosted=headers.get("hx-boosted", "").lower() == "true",
        target=headers.get("hx-target"),
        trigger=headers.get("hx-trigger"),
        trigger_name=headers.get("hx-trigger-name"),
        current_url=headers.get("hx-current-url"),
        prompt=headers.get("hx-prompt"),
    )

htmx_response_headers

htmx_response_headers

htmx_response_headers(
    *,
    trigger: str | None = None,
    trigger_after_settle: str | None = None,
    trigger_after_swap: str | None = None,
    redirect: str | None = None,
    refresh: bool = False,
    retarget: str | None = None,
    reswap: str | None = None,
    push_url: str | bool | None = None,
    replace_url: str | bool | None = None,
) -> dict[str, str]

Build HTMX response headers.

Use with any response type to control HTMX client-side behavior.

Parameters:

Name Type Description Default
trigger str | None

Trigger client-side events after response is received.

None
trigger_after_settle str | None

Trigger events after the settling step.

None
trigger_after_swap str | None

Trigger events after the swap step.

None
redirect str | None

Redirect the browser to a new URL.

None
refresh bool

If True, trigger a full page refresh.

False
retarget str | None

Override the swap target CSS selector.

None
reswap str | None

Override the swap strategy (innerHTML, outerHTML, etc.).

None
push_url str | bool | None

Push a URL into the browser history.

None
replace_url str | bool | None

Replace the current URL in the browser.

None

Returns:

Type Description
dict[str, str]

Dict of HTMX response headers.

Example

headers = htmx_response_headers(trigger="itemAdded", reswap="outerHTML") return HTMLResult(content="

  • New item
  • ", headers=headers)

    Source code in src/agenticapi/interface/htmx.py
    def htmx_response_headers(
        *,
        trigger: str | None = None,
        trigger_after_settle: str | None = None,
        trigger_after_swap: str | None = None,
        redirect: str | None = None,
        refresh: bool = False,
        retarget: str | None = None,
        reswap: str | None = None,
        push_url: str | bool | None = None,
        replace_url: str | bool | None = None,
    ) -> dict[str, str]:
        """Build HTMX response headers.
    
        Use with any response type to control HTMX client-side behavior.
    
        Args:
            trigger: Trigger client-side events after response is received.
            trigger_after_settle: Trigger events after the settling step.
            trigger_after_swap: Trigger events after the swap step.
            redirect: Redirect the browser to a new URL.
            refresh: If True, trigger a full page refresh.
            retarget: Override the swap target CSS selector.
            reswap: Override the swap strategy (innerHTML, outerHTML, etc.).
            push_url: Push a URL into the browser history.
            replace_url: Replace the current URL in the browser.
    
        Returns:
            Dict of HTMX response headers.
    
        Example:
            headers = htmx_response_headers(trigger="itemAdded", reswap="outerHTML")
            return HTMLResult(content="<li>New item</li>", headers=headers)
        """
        headers: dict[str, str] = {}
        if trigger is not None:
            headers["HX-Trigger"] = trigger
        if trigger_after_settle is not None:
            headers["HX-Trigger-After-Settle"] = trigger_after_settle
        if trigger_after_swap is not None:
            headers["HX-Trigger-After-Swap"] = trigger_after_swap
        if redirect is not None:
            headers["HX-Redirect"] = redirect
        if refresh:
            headers["HX-Refresh"] = "true"
        if retarget is not None:
            headers["HX-Retarget"] = retarget
        if reswap is not None:
            headers["HX-Reswap"] = reswap
        if push_url is not None:
            headers["HX-Push-Url"] = str(push_url).lower() if isinstance(push_url, bool) else push_url
        if replace_url is not None:
            headers["HX-Replace-Url"] = str(replace_url).lower() if isinstance(replace_url, bool) else replace_url
        return headers