本文へ移動
cccskills
無料GitHub で公開

litestar-htmx

Auto-activate for litestar_htmx, HTMXPlugin, HTMXConfig, HTMXRequest, HTMXTemplate, HXLocation, ReplaceUrl, TriggerEvent, or HX-* headers. Not for client-only HTMX — use litestar-vite.

インストール方法を見る

含まれるファイル(2)

  • SKILL.md14.4 KB
  • references/litestar_vite.md3.6 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

litestar-htmx

litestar-htmx is the standalone Litestar integration for HTMX. Version 0.5.0 ships the litestar_htmx import package with request helpers, an optional application plugin, template responses, and typed HTMX response-header helpers.

Code Style Rules

  • Import the integration from litestar_htmx, never the litestar.plugins.htmx compatibility re-export shim.
  • Use HTMXRequest when handlers inspect HTMX request headers.
  • Return template fragments from HTMX endpoints; keep full-page routes and fragment routes distinct.
  • Use the response classes for HX-* headers; do not assemble those headers by hand.
  • Keep browser-side HTMX extensions separate from this server package.

Quick Reference

Configure the plugin

from litestar import Litestar
from litestar_htmx import HTMXPlugin

app = Litestar(
    route_handlers=[...],
    plugins=[HTMXPlugin()],
)

HTMXPlugin() is the convenience path: its on_app_init hook registers HTMXRequest and all ten HTMX response classes in app_config.signature_types. Its default HTMXConfig(set_request_class_globally=True) sets HTMXRequest only when app_config.request_class is None.

Preserve an existing custom request class by extending HTMXRequest:

from litestar_htmx import HTMXRequest


class ApplicationRequest(HTMXRequest):
    """Application request with HTMX helpers."""

If the application only needs response helpers, use HTMXConfig(set_request_class_globally=False). To inspect request.htmx, configure HTMXRequest (or a subclass) as the application request class. The plugin never replaces a request class already present in AppConfig.

The plugin itself is optional. Applications can instead set request_class=HTMXRequest directly and return the response subclasses without registering HTMXPlugin.

Inspect request headers

request.htmx is always an HTMXDetails object. Its truth value is True only when HX-Request is exactly "true".

from litestar import get
from litestar.response import Template
from litestar_htmx import HTMXRequest


@get("/items")
async def list_items(request: HTMXRequest) -> Template:
    template_name = "partials/item-list.html" if request.htmx else "pages/items.html"
    return Template(template_name=template_name, context={"items": []})

Available request helpers:

PropertySourceResult
bool(request.htmx)HX-RequestWhether this is an HTMX request
request.htmx.boostedHX-Boostedbool
request.htmx.current_urlHX-Current-URLstr | None
request.htmx.current_url_abs_pathHX-Current-URLSame-origin path, query, and fragment, or None
request.htmx.history_restore_requestHX-History-Restore-Requestbool
request.htmx.promptHX-Promptstr | None
request.htmx.targetHX-Targetstr | None
request.htmx.triggerHX-Triggerstr | None
request.htmx.trigger_nameHX-Trigger-Namestr | None
request.htmx.triggering_eventTriggering-EventDecoded JSON value, or None

triggering_event is supplied by HTMX's event-header extension and decoded using the active route handler's type_decoders. Malformed JSON resolves to None. Headers accompanied by <Header>-URI-AutoEncoded: true are URL-decoded before use.

Return template fragments with HTMX headers

HTMXTemplate extends Litestar's Template. Annotate handlers with Template, then pass normal Template arguments plus HTMX-specific options:

from litestar import get
from litestar.response import Template
from litestar_htmx import HTMXTemplate


@get("/items/fragment")
async def item_list() -> Template:
    return HTMXTemplate(
        template_name="partials/item-list.html",
        context={"items": []},
        push_url=False,
        re_swap="outerHTML",
        re_target="#item-list",
        trigger_event="itemsLoaded",
        params={"count": 0},
        after="receive",
    )

trigger_event, params, and after form one event declaration. When trigger_event is set, after must be "receive", "settle", or "swap" (leaving after=None raises ImproperlyConfiguredException). HTMXTemplate supports push_url, re_swap, re_target, trigger_event, params, and after; it does not accept replace_url.

Response helper signatures

All helpers are exported from litestar_htmx and litestar_htmx.response.

HelperConstructorBehavior
HXStopPollingHXStopPolling()Returns status 286 (HTMX_STOP_POLLING)
ClientRedirectClientRedirect(redirect_to)Status 200; sets URL-quoted HX-Redirect and deletes Location
ClientRefreshClientRefresh()Status 200; sets HX-Refresh: true
PushUrlPushUrl(content, push_url, **kwargs)Status 200; sets HX-Push-Url
ReplaceUrlReplaceUrl(content, replace_url, **kwargs)Status 200; sets HX-Replace-Url
ReswapReswap(content, method, **kwargs)Sets HX-Reswap
RetargetRetarget(content, target, **kwargs)Sets HX-Retarget
TriggerEventTriggerEvent(content, name, after, params=None, **kwargs)Sets HX-Trigger, HX-Trigger-After-Settle, or HX-Trigger-After-Swap
HXLocationHXLocation(redirect_to, source=None, event=None, target=None, select=None, swap=None, hx_headers=None, values=None, **kwargs)Status 200; sets JSON in HX-Location and deletes Location
HTMXTemplateHTMXTemplate(push_url=None, re_swap=None, re_target=None, trigger_event=None, params=None, after=None, **kwargs)Template subclass combining HX-Push-Url, HX-Reswap, HX-Retarget, and trigger headers

Pass a URL str to push_url or replace_url to update history, or False (or "False") to emit "false" and prevent the history update. Do not pass True: any bool value is serialized as "false".

Exported types and header enum

litestar_htmx exports the typing definitions (from litestar_htmx.types) and the HTMXHeaders enum (from litestar_htmx.request and litestar_htmx._utils) used across request and response helpers:

ExportKindDefinition / Values
HTMXHeadersstr, EnumRequest and response header names (REQUEST, BOOSTED, CURRENT_URL, HISTORY_RESTORE_REQUEST, PROMPT, TARGET, TRIGGER_ID, TRIGGER_NAME, TRIGGERING_EVENT, REDIRECT, REFRESH, PUSH_URL, REPLACE_URL, RE_SWAP, RE_TARGET, LOCATION, TRIGGER_EVENT, TRIGGER_AFTER_SETTLE, TRIGGER_AFTER_SWAP)
EventAfterTypeLiteral"receive" | "settle" | "swap" | None
PushUrlTypeUnionstr | bool (use URL str or False)
ReSwapMethodLiteral"innerHTML" | "outerHTML" | "beforebegin" | "afterbegin" | "beforeend" | "afterend" | "delete" | "none" | None
LocationTypeTypedDictpath, source, event, target, select, swap, values, hx_headers
TriggerEventTypeTypedDictname, params, after
HtmxHeaderTypeTypedDict(total=False)location, redirect, refresh, push_url, replace_url, re_swap, re_target, trigger_event

Soft navigation with HXLocation

Use HXLocation for an HTMX navigation request without a full-page reload. select chooses a fragment from the fetched response before it is swapped:

from litestar import post
from litestar_htmx import HXLocation


@post("/items")
async def create_item() -> HXLocation:
    return HXLocation(
        redirect_to="/items",
        source="#create-item",
        event="submit",
        target="#content",
        select="#item-list",
        swap="innerHTML",
        hx_headers={"X-View": "compact"},
        values={"created": "true"},
    )

The response uses status 200, carries HX-Location, and removes the ordinary Location header.

Trigger an event while returning content

TriggerEvent requires the response content, event name, and after phase:

from litestar import post
from litestar_htmx import TriggerEvent


@post("/items")
async def create_item() -> TriggerEvent[str]:
    return TriggerEvent(
        content="<li>Saved</li>",
        name="itemCreated",
        after="swap",
        params={"id": 42},
        media_type="text/html",
    )

Prefer HTMXTemplate when the content is HTML assembled from application data.

Litestar Vite is a separate client layer

The standalone package owns Python request parsing and response headers:

from litestar_htmx import HTMXPlugin, HTMXRequest, HTMXTemplate

Litestar Vite's hx-ext="litestar" JSON templating and CSRF integration come from the separate litestar-vite-plugin/helpers JavaScript export. They are not installed, registered, or enabled by HTMXPlugin(). Use them only when the project already uses Litestar Vite and needs client-side JSON swaps. See Litestar Vite Integration.

<workflow>

Workflow

  1. Check the project's installed litestar-htmx version and existing request class.
  2. Register HTMXPlugin() or set request_class=HTMXRequest directly. Extend HTMXRequest when the application needs custom request behavior.
  3. Separate full-page endpoints from fragment endpoints. Branch on request.htmx only when one URL intentionally supports both.
  4. Render fragments with Template or HTMXTemplate.
  5. Select the narrow response helper matching the required HTMX header.
  6. Configure CSRF protection for every state-changing HTMX request.
  7. Test the response body, status, and exact HX-* header.
  8. Add Litestar Vite's client extension only for bundled assets, CSRF header injection, or JSON templating.
</workflow> <guardrails>

Guardrails

  • Use litestar_htmx, never litestar.plugins.htmx. The 0.5.0 package is a standalone distribution; litestar.plugins.htmx is only a compatibility re-export shim.
  • Pass every required response-helper argument. TriggerEvent requires content, name, and a non-null after ("receive", "settle", or "swap"); PushUrl, ReplaceUrl, Reswap, and Retarget also require content.
  • Pass a URL str or False for push_url and replace_url. Any boolean value (including True) is serialized as "false".
  • Use select= on HXLocation to choose returned content. Do not confuse it with target=, which chooses the receiving element.
  • Do not assume HTMXPlugin overrides an existing request class. It preserves a non-null AppConfig.request_class.
  • Do not treat request.htmx as an optional object. Test its truth value to identify HTMX requests.
  • Do not send a normal redirect for HXLocation or ClientRedirect. These helpers return 200 with HTMX response headers and delete Location.
  • Do not attribute hx-ext="litestar" to litestar-htmx. That browser extension ships with Litestar Vite's npm package.
  • Do not return unsanitized, concatenated HTML. Render templates so escaping and template caching remain intact.
</guardrails> <validation>

Validation Checkpoint

  • Imports use litestar_htmx, not litestar.plugins.htmx
  • HTMXPlugin() or request_class=HTMXRequest wires request helpers
  • A custom global request class extends HTMXRequest
  • Full pages and HTMX fragments have explicit boundaries
  • TriggerEvent and HTMXTemplate(trigger_event=...) set after to "receive", "settle", or "swap"
  • PushUrl, ReplaceUrl, and HTMXTemplate(push_url=...) pass a URL str or False (never True)
  • HXLocation.select and HXLocation.target serve distinct purposes
  • State-changing HTMX requests include the application's CSRF token
  • Tests assert the exact status, body, and HX-* response header
  • Litestar Vite client-extension guidance is identified as a separate layer
</validation> <example>

Example

Return a fragment, retarget the swap, prevent a history update, and verify the HTMX response:

from litestar import Controller, get
from litestar.response import Template
from litestar_htmx import HTMXRequest, HTMXTemplate


class ItemController(Controller):
    path = "/items"

    @get("/")
    async def index(self, request: HTMXRequest) -> Template:
        items = [{"id": 1, "name": "Widget"}]
        if request.htmx:
            return HTMXTemplate(
                template_name="partials/item-list.html",
                context={"items": items},
                re_target="#item-list",
                re_swap="outerHTML",
                push_url=False,
            )
        return Template(template_name="pages/items.html", context={"items": items})
async def test_htmx_item_list(client) -> None:
    response = await client.get(
        "/items/",
        headers={"HX-Request": "true", "HX-Target": "item-list"},
    )

    assert response.status_code == 200
    assert response.headers["HX-Retarget"] == "#item-list"
    assert response.headers["HX-Reswap"] == "outerHTML"
    assert response.headers["HX-Push-Url"] == "false"
    assert "<html" not in response.text
</example>

References Index

  • Litestar Vite Integration — Keep the standalone Python package distinct from Litestar Vite's browser extension.
  • Litestar — Application setup, templates, and lifecycle fundamentals.
  • Litestar Vite — Asset bundling, template mode, HMR, and the client helper package.
  • Litestar Testing — Async clients and application fixtures.

Official References

Shared Styleguide Baseline

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Auto-activate for advanced_alchemy, alembic/, SQLAlchemyAsyncRepositoryService, SQLAlchemyAsyncConfig, repository_type, service_class, filters, or storage. Not for raw SQLAlchemy — use sqlspec.

日本語の概要は準備中です。原文の説明を表示しています。

litestar-org/litestar-skills162026年10月4日 更新

litestar

無料

Auto-activate for Litestar, Controller, Router, @get/@post, FromPath, MsgspecDTO, OpenAPIConfig, Provide, FromDishka, Guard, ASGIMiddleware, HTTPException, ChannelsPlugin, or WebSocket. Not for standalone libs.

日本語の概要は準備中です。原文の説明を表示しています。

litestar-org/litestar-skills162026年10月4日 更新

Auto-activate for Google ADK, LlmAgent, Runner, SQLSpecSessionService, google-genai, AgentRuntime, SpecTree, DynamicWorkflow, FunctionTool, or SSE agent chats. Not for offline ML training.

日本語の概要は準備中です。原文の説明を表示しています。

litestar-org/litestar-skills162026年10月4日 更新

Auto-activate for litestar_autowire, AutowirePlugin, AutowireConfig, domain_packages, AutowireIntegration, AutowireLoader, or clear_autowire_cache. Not for manual Router composition — use explicit routes.

日本語の概要は準備中です。原文の説明を表示しています。

litestar-org/litestar-skills162026年10月4日 更新

Auto-activate for uv build, hatch build, PyApp, PYAPP_*, wheel assets, GitHub release matrices, cargo-zigbuild, or python-build-standalone. Not for runtime deployment.

日本語の概要は準備中です。原文の説明を表示しています。

litestar-org/litestar-skills162026年10月4日 更新

Auto-activate for Dockerfile, compose, Railway, Cloud Run, GKE, systemd, Kubernetes, Terraform, deploy scripts, or granian/litestar run at runtime. Not for packaging artifacts.

日本語の概要は準備中です。原文の説明を表示しています。

litestar-org/litestar-skills162026年10月4日 更新

litestar-org のスキルをすべて見る

このスキルの問題を報告する