{"id":"af64b697-b2cb-4ae1-a060-61b9c427937c","shortId":"4uGXLS","kind":"skill","title":"litestar-htmx","tagline":"Auto-activate for litestar_htmx imports, HTMXPlugin, HTMXRequest, HTMXTemplate, TriggerEvent, PushUrl, HXLocation, hx-* attributes in Litestar templates, or partial HTML responses. Use when building HTMX-powered Litestar handlers, templates, and server-triggered client events. No","description":"# litestar-htmx\n\nLitestar has first-party HTMX support in `litestar_htmx`. It exposes `HTMXPlugin`, `HTMXRequest` (request-side helpers), `HTMXTemplate` (template response with HTMX headers), and HTMX-specific response objects (`TriggerEvent`, `Reswap`, `Retarget`, `PushUrl`, `HXLocation`, `ClientRedirect`, `ClientRefresh`).\n\nThis skill is **Litestar-specific**. For generic HTMX `hx-*` attributes and patterns that aren't Litestar-bound, refer directly to <https://htmx.org/docs/>.\n\n## Code Style Rules\n\n- PEP 604 unions: `T | None`, never `Optional[T]`\n- Consumer Litestar app modules MAY use `from __future__ import annotations`\n- Async all I/O — handlers are `async def`\n- Return partial HTML, not full pages, from HTMX-targeted endpoints\n- Use Jinja2 (or Mako) templates for partials; do not string-concat HTML\n\n## Quick Reference\n\n### HTMXRequest\n\n`HTMXRequest` is a `Request` subclass with HTMX-aware properties:\n\n```python\nfrom litestar import get\nfrom litestar_htmx import HTMXRequest\n\n@get(\"/items\")\nasync def list_items(request: HTMXRequest) -> ...:\n    if request.htmx:                  # True if HX-Request header present\n        ...                           # return partial\n    else:\n        ...                           # full page\n\n    # Other helpers\n    request.htmx.target               # HX-Target header (str | None)\n    request.htmx.trigger              # HX-Trigger header\n    request.htmx.trigger_name         # HX-Trigger-Name header\n    request.htmx.boosted              # HX-Boosted (bool)\n    request.htmx.current_url          # HX-Current-URL\n    request.htmx.history_restore_request\n    request.htmx.prompt               # HX-Prompt (user input from hx-prompt)\n```\n\nWire it into the app:\n\n```python\nfrom litestar import Litestar\nfrom litestar_htmx import HTMXPlugin\n\napp = Litestar(route_handlers=[...], plugins=[HTMXPlugin()])\n```\n\n### HTMXTemplate + Partial HTML\n\nReturn Jinja partials from handlers:\n\n```python\nfrom litestar import get\nfrom litestar.response import Template\n\n@get(\"/items\")\nasync def list_items() -> Template:\n    items = await item_service.list()\n    return Template(template_name=\"partials/item_list.html\", context={\"items\": items})\n```\n\nFor HTMX-targeted endpoints, the template is a fragment (no `<html>` / `<body>`), e.g.:\n\n```html\n<!-- partials/item_list.html -->\n<ul id=\"item-list\">\n  {% for item in items %}\n    <li>{{ item.name }}</li>\n  {% endfor %}\n</ul>\n```\n\n### Server-driven HTMX Responses\n\n| Response Object | Purpose |\n| --- | --- |\n| `TriggerEvent(name, after=\"receive\", params={...})` | Sets `HX-Trigger` / `HX-Trigger-After-Swap` / `HX-Trigger-After-Settle` |\n| `ClientRedirect(redirect_to=...)` | Sets `HX-Redirect` — client-side hard redirect |\n| `ClientRefresh()` | Sets `HX-Refresh: true` |\n| `PushUrl(push_url=...)` | Sets `HX-Push-Url` — adds entry to browser history |\n| `Reswap(method=\"outerHTML\")` | Sets `HX-Reswap` — overrides client `hx-swap` |\n| `Retarget(target=\"#new\")` | Sets `HX-Retarget` — overrides client `hx-target` |\n| `HXLocation(redirect_to=...)` | Sets `HX-Location` — client-side soft navigation |\n| `HXStopPolling()` | Returns 286 — HTMX stops polling on this element |\n\nExample: trigger a custom event after a successful save:\n\n```python\nfrom litestar_htmx import TriggerEvent\n\n@post(\"/items\")\nasync def create_item(data: ItemCreate) -> TriggerEvent:\n    item = await item_service.create(data)\n    return TriggerEvent(\n        name=\"itemCreated\",\n        params={\"id\": item.id, \"name\": item.name},\n        after=\"receive\",\n    )\n```\n\n### OOB (Out-of-Band) Swaps\n\nFor a single response that updates multiple regions, render multiple fragments and use `hx-swap-oob`:\n\n```html\n<!-- main response -->\n<div id=\"form-result\">Saved!</div>\n\n<!-- OOB updates -->\n<div id=\"notification\" hx-swap-oob=\"true\">New notification!</div>\n<div id=\"counter\" hx-swap-oob=\"innerHTML\">42</div>\n```\n\nReturn the combined HTML as a `Template` or `HTMXTemplate`.\n\n### CSRF\n\nUse Litestar's CSRF middleware; expose the token to templates as a `<meta>` tag and forward it via HTMX:\n\n```html\n<meta name=\"csrf-token\" content=\"{{ request.scope['csrf_token'] }}\">\n<script>\n  document.body.addEventListener('htmx:configRequest', (e) => {\n    e.detail.headers['X-CSRF-Token'] =\n      document.querySelector('meta[name=\"csrf-token\"]').content;\n  });\n</script>\n```\n\n### Pairing with `litestar-vite` (template mode)\n\nFor HTMX projects with bundled JS/CSS and HMR, use `litestar-vite` in `template` mode. Vite bundles HTMX + extensions + CSS; Litestar returns partials. See `../litestar-vite/SKILL.md` and [`../litestar-vite/references/modes.md`](../litestar-vite/references/modes.md#htmx--template-mode).\n\n```html\n<!-- base.html.j2 -->\n<!DOCTYPE html>\n<html>\n<head>\n  {{ vite_hmr() }}\n  {{ vite('resources/main.js') }}\n</head>\n<body hx-ext=\"litestar\">          <!-- enables the Litestar client extension -->\n  {% block content %}{% endblock %}\n</body>\n</html>\n```\n\n### The `hx-ext=\"litestar\"` client-side templating extension\n\nActivating `hx-ext=\"litestar\"` (on `<body>` or any enclosing element) unlocks **client-side JSON rendering** via `<template>` tags. When an HTMX swap uses `hx-swap=\"json\"`, the response body is parsed as JSON and matched against `ls-*` attributes on descendant `<template>` tags.\n\nThis lets you render JSON API responses as HTML **without** server-side templates — complementary to the partial-HTML pattern.\n\n| Attribute | Purpose |\n| --- | --- |\n| `ls-for=\"item in $data\"` | Iterate over the JSON response array |\n| `ls-key=\"item.id\"` | Stable key for list reconciliation |\n| `ls-if=\"condition\"` | Render only when truthy |\n| `ls-else` | Fallback block for `ls-if` |\n| `${expression}` | Interpolate JS expression into text content |\n| `:attr=\"expression\"` | Dynamic attribute binding |\n| `$data` | The raw JSON response body |\n\nArray rendering:\n\n```html\n<button hx-get=\"/api/books\" hx-target=\"#books\" hx-swap=\"json\">Load</button>\n\n<div id=\"books\">\n  <template ls-for=\"book in $data\" ls-key=\"book.id\">\n    <article :id=\"`book-${book.id}`\">\n      <h3>${book.title}</h3>\n      <p>${book.author} • ${book.year}</p>\n    </article>\n  </template>\n</div>\n```\n\nSingle-item rendering (properties on `$data` accessible directly via prototype inheritance):\n\n```html\n<div hx-get=\"/api/books/1\" hx-target=\"#book\" hx-swap=\"json\">\n  <template ls-if=\"id\">\n    <h3>${title}</h3>\n    <p>${author} • ${year}</p>\n    <div>\n      <template ls-for=\"tag in tags\">\n        <span>${tag}</span>\n      </template>\n    </div>\n  </template>\n  <template ls-else>\n    <p>Click to load…</p>\n  </template>\n</div>\n```\n\n**When to use this vs server-side partials:**\n\n| Case | Approach |\n| --- | --- |\n| Data shape simple, rendering trivial, already have JSON endpoint | Client `ls-*` templating (no `HTMXTemplate`) |\n| Complex conditionals, auth-sensitive fields, heavy formatting | Server partials via `HTMXTemplate` |\n| Same endpoint serving both JSON (for JS clients) and HTML (for HTMX clients) | Branch on `request.htmx`; return JSON always and let `ls-*` render it for HTMX consumers |\n\nBoth coexist in one page. The canonical `jinja-htmx` example in `litestar-vite/examples/jinja-htmx/` demonstrates both side by side.\n\n### Common HTMX Attributes (quick refresher)\n\n```html\n<!-- Trigger types -->\n<button hx-get=\"/items\" hx-target=\"#item-list\">Load</button>\n<button hx-post=\"/items\" hx-vals='{\"name\":\"x\"}'>Create</button>\n<button hx-delete=\"/items/1\" hx-confirm=\"Are you sure?\">Delete</button>\n\n<!-- Triggers -->\n<input hx-get=\"/search\" hx-trigger=\"keyup changed delay:500ms\">\n<div hx-get=\"/updates\" hx-trigger=\"every 5s\">Polling</div>\n\n<!-- Swaps -->\n<div hx-get=\"/x\" hx-swap=\"outerHTML\">Replace element</div>\n<div hx-get=\"/x\" hx-swap=\"beforeend\">Append</div>\n\n<!-- Boost -->\n<a hx-boost=\"true\" href=\"/page\">Boost</a>\n<a hx-get=\"/page\" hx-push-url=\"true\">Navigate with history</a>\n```\n\nFor full HTMX attribute reference, see <https://htmx.org/reference/>.\n\n<workflow>\n\n## Workflow\n\n### Step 1: Wire HTMXRequest\n\nPass `request_class=HTMXRequest` to `Litestar(...)`. All handlers can now type-annotate `request: HTMXRequest`.\n\n### Step 2: Decide Page vs Partial Boundaries\n\nFor each route, decide:\n\n- **Page route** — returns full layout (one `Template` rendering `base.html`)\n- **Partial route** — returns a fragment used by `hx-get`/`hx-post`\n\nCluster partial routes under a sub-path like `/htmx/...` or differentiate by `request.htmx`.\n\n### Step 3: Templates for Partials\n\nBuild Jinja2 partials as fragments — no `<html>`, no `<body>`. Mount your full-page templates separately.\n\n### Step 4: Server-driven Behavior\n\nUse `TriggerEvent`, `Refresh`, `Reswap`, `Retarget` to push behavior from the server. Avoid putting business logic in the client.\n\n### Step 5: Pair with `litestar-vite` (optional)\n\nIf the app needs bundled CSS/JS or HMR for non-HTMX assets, add `litestar-vite` in `template` or `htmx` mode. See `../litestar-vite/SKILL.md`.\n\n### Step 6: CSRF + Auth\n\nApply Litestar Guards / middleware as usual. Include CSRF token via `htmx:configRequest`.\n\n### Step 7: Test\n\nUse `litestar.testing.AsyncTestClient` with the `HX-Request: true` header to exercise partial responses. See `../litestar-testing/SKILL.md`.\n\n```python\nresp = await client.get(\"/items\", headers={\"HX-Request\": \"true\", \"HX-Target\": \"#item-list\"})\nassert \"<ul\" in resp.text\n```\n\n</workflow>\n\n<guardrails>\n\n## Guardrails\n\n- **Use `litestar_htmx`**, not generic ASGI patterns — the plugin integrates with Litestar's lifecycle, OpenAPI, and DI.\n- **Register `HTMXPlugin()`** at the app level — handlers shouldn't construct `HTMXRequest` ad-hoc.\n- **Return partial HTML for HTMX-targeted routes** — never return a full layout to an `hx-get` target.\n- **Use `Template` (Litestar response) — never string-concat HTML** — XSS risk and template caching benefits.\n- **CSRF protection applies to HTMX too** — non-GET HTMX requests must include the CSRF token (header preferred).\n- **Use server-driven response objects** (`TriggerEvent`, `Reswap`, `Retarget`) rather than ad-hoc JS — keeps logic on the server.\n- **Pair with `litestar-vite` only when you need bundled assets / HMR** — pure HTMX with a CDN htmx.min.js works fine without Vite.\n- **Don't return JSON to HTMX endpoints** — HTMX expects HTML; JSON breaks `hx-swap` semantics.\n- **Test with `HX-Request: true`** to exercise the HTMX path.\n\n</guardrails>\n\n<validation>\n\n### Validation Checkpoint\n\nBefore delivering Litestar + HTMX code, verify:\n\n- [ ] `HTMXPlugin()` is registered on the `Litestar(...)` constructor\n- [ ] HTMX-targeted routes return Jinja2 fragments (no `<html>` / `<body>`)\n- [ ] `Template` response object used (not raw HTML strings)\n- [ ] CSRF middleware enabled; token forwarded via `htmx:configRequest`\n- [ ] Server-driven behavior uses `TriggerEvent` / `Reswap` / `Retarget` (not ad-hoc JS)\n- [ ] Tests assert against partial HTML with `HX-Request: true` header\n- [ ] If using `litestar-vite`, mode is `template`\n\n</validation>\n\n<example>\n\n## Example\n\n**Task:** Items page with an HTMX-driven create form, OOB notification, and server-triggered refresh event.\n\n```python\n# app/domain/items/controllers.py\nfrom litestar import Controller, get, post\nfrom litestar.response import Template\nfrom litestar_htmx import HTMXRequest, TriggerEvent\n\n\nclass ItemController(Controller):\n    path = \"/items\"\n\n    @get(\"/\")\n    async def index(self) -> Template:\n        items = await item_service.list()\n        return Template(\"pages/items.html\", context={\"items\": items})\n\n    @get(\"/list\")\n    async def list_partial(self, request: HTMXRequest) -> Template:\n        \"\"\"Partial used by hx-get on initial load and after create.\"\"\"\n        items = await item_service.list()\n        return Template(\"partials/item_list.html\", context={\"items\": items})\n\n    @post(\"/\")\n    async def create(self, data: ItemCreate) -> TriggerEvent:\n        item = await item_service.create(data)\n        return TriggerEvent(\n            name=\"itemCreated\",\n            params={\"id\": item.id, \"name\": item.name},\n            after=\"receive\",\n        )\n```\n\n```html\n<!-- pages/items.html -->\n{% extends \"base.html\" %}\n\n{% block content %}\n  <form\n    hx-post=\"/items/\"\n    hx-target=\"#item-list\"\n    hx-swap=\"outerHTML\"\n    hx-on::after-request=\"this.reset()\"\n  >\n    <input name=\"name\" required>\n    <button type=\"submit\">Add</button>\n  </form>\n\n  <div hx-get=\"/items/list\" hx-trigger=\"itemCreated from:body\" hx-swap=\"outerHTML\">\n    {% include \"partials/item_list.html\" %}\n  </div>\n{% endblock %}\n```\n\n```html\n<!-- partials/item_list.html -->\n<ul id=\"item-list\">\n  {% for item in items %}\n    <li>{{ item.name }}</li>\n  {% endfor %}\n</ul>\n```\n\n```python\n# tests/test_items.py\nasync def test_create_item_triggers_event(client):\n    resp = await client.post(\n        \"/items/\",\n        json={\"name\": \"Widget\"},\n        headers={\"HX-Request\": \"true\"},\n    )\n    assert resp.status_code == 201\n    assert \"itemCreated\" in resp.headers[\"HX-Trigger\"]\n```\n\n</example>\n\n---\n\n## References Index\n\n- **[litestar-vite Integration](references/litestar_vite.md)** — Bundling HTMX + custom JS/CSS with `litestar-vite` in template mode.\n\n## Cross-References\n\n- **[litestar](../litestar/SKILL.md)** — Litestar fundamentals (Templates, Controllers, Guards, middleware).\n- **[litestar-vite](../litestar-vite/SKILL.md)** — HTMX + Jinja with Vite-bundled assets.\n\n## Official References\n\n- <https://docs.litestar.dev/2/usage/htmx.html>\n- <https://htmx.org/docs/>\n- <https://htmx.org/reference/>\n- <https://htmx.org/migration-guide-htmx-1/>\n- <https://extensions.htmx.org/>\n\n## Shared Styleguide Baseline\n\n- [General Principles](../litestar-styleguide/references/general.md)\n- [Litestar](../litestar-styleguide/references/litestar.md)","tags":["litestar","htmx","skills","litestar-org","advanced-alchemy","agent-skills","agentskills","ai-agents","claude-code-plugin","claude-code-skills","gemini-cli-extension","inertia"],"capabilities":["skill","source-litestar-org","skill-litestar-htmx","topic-advanced-alchemy","topic-agent-skills","topic-agentskills","topic-ai-agents","topic-claude-code-plugin","topic-claude-code-skills","topic-gemini-cli-extension","topic-htmx","topic-inertia","topic-litestar","topic-mcp","topic-python"],"categories":["litestar-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/litestar-org/litestar-skills/litestar-htmx","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add litestar-org/litestar-skills","source_repo":"https://github.com/litestar-org/litestar-skills","install_from":"skills.sh"}},"qualityScore":"0.453","qualityRationale":"deterministic score 0.45 from registry signals: · indexed on github topic:agent-skills · 7 github stars · SKILL.md body (13,689 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T19:13:54.042Z","embedding":null,"createdAt":"2026-05-18T13:20:57.589Z","updatedAt":"2026-05-18T19:13:54.042Z","lastSeenAt":"2026-05-18T19:13:54.042Z","tsv":"'/2/usage/htmx.html':1463 '/docs/':106,1466 '/examples/jinja-htmx':807 '/htmx':901 '/items':183,288,443,1019,1300,1399 '/list':1317 '/litestar-styleguide/references/general.md':1479 '/litestar-styleguide/references/litestar.md':1481 '/litestar-testing/skill.md':1014 '/litestar-vite/references/modes.md':556,557 '/litestar-vite/skill.md':554,980,1451 '/litestar/skill.md':1441 '/migration-guide-htmx-1/':1472 '/reference/':838,1469 '1':841 '2':860 '201':1411 '286':420 '3':907 '4':926 '42':493 '5':950 '6':982 '604':111 '7':998 'access':715 'activ':6,580 'ad':1065,1131,1237 'ad-hoc':1064,1130,1236 'add':377,970,1375 'alreadi':744 'alway':783 'annot':127,856 'api':627 'app':120,253,264,959,1057 'app/domain/items/controllers.py':1279 'append':825 'appli':985,1103 'approach':738 'aren':96 'array':656,701 'asgi':1041 'assert':1031,1241,1408,1412 'asset':969,1149,1458 'async':128,133,184,289,444,1302,1318,1348,1388 'attr':690 'attribut':18,92,618,643,693,815,833 'auth':756,984 'auth-sensit':755 'author':722 'auto':5 'auto-activ':4 'avoid':942 'await':295,452,1017,1308,1339,1356,1397 'awar':170 'band':470 'base.html':878,1372 'baselin':1476 'behavior':930,938,1230 'benefit':1100 'bind':694 'block':567,678,1373 'bodi':609,700 'book.author':706 'book.title':705 'book.year':707 'bool':229 'boost':228,826 'bound':100 'boundari':865 'branch':778 'break':1172 'browser':380 'build':28,911 'bundl':534,546,961,1148,1426,1457 'busi':944 'cach':1099 'canon':798 'case':737 'cdn':1155 'checkpoint':1189 'class':846,1296 'click':725 'client':39,359,390,402,414,576,592,748,772,777,948,1395 'client-sid':358,413,575,591 'client.get':1018 'client.post':1398 'clientredirect':80,351 'clientrefresh':81,363 'cluster':892 'code':107,1194,1410 'coexist':793 'combin':496 'common':813 'complementari':636 'complex':753 'concat':157,1093 'condit':669,754 'configrequest':996,1226 'construct':1062 'constructor':1202 'consum':118,791 'content':568,689,1374 'context':302,1313,1344 'control':1283,1298,1445 'creat':446,820,1268,1337,1350,1391 'cross':1438 'cross-refer':1437 'csrf':503,507,983,992,1101,1115,1219 'css':549 'css/js':962 'current':234 'custom':430,1428 'data':448,454,650,695,714,739,1352,1358 'decid':861,869 'def':134,185,290,445,1303,1319,1349,1389 'delet':821 'deliv':1191 'demonstr':808 'descend':620 'di':1052 'differenti':903 'direct':102,716 'docs.litestar.dev':1462 'docs.litestar.dev/2/usage/htmx.html':1461 'driven':326,929,1122,1229,1267 'dynam':692 'e.g':316 'element':426,589,824 'els':201,676 'enabl':1221 'enclos':588 'endblock':569,1378 'endfor':323,1385 'endpoint':145,309,747,766,1167 'entri':378 'event':40,431,1277,1394 'exampl':427,802,1259 'exercis':1010,1184 'expect':1169 'expos':56,509 'express':683,686,691 'ext':573,583 'extend':1371 'extens':548,579 'extensions.htmx.org':1473 'fallback':677 'field':758 'fine':1158 'first':48 'first-parti':47 'form':1269 'format':760 'forward':518,1223 'fragment':314,482,883,915,1209 'full':139,202,831,873,921,1078 'full-pag':920 'fundament':1443 'futur':125 'general':1477 'generic':89,1040 'get':176,182,282,287,888,1084,1109,1284,1301,1316,1331 'guard':987,1446 'guardrail':1035 'handler':33,131,267,277,851,1059 'hard':361 'header':68,197,210,217,224,1008,1020,1117,1250,1403 'heavi':759 'helper':62,205 'histori':381,829 'hmr':537,564,964,1150 'hoc':1066,1132,1238 'html':24,137,158,272,317,489,497,522,562,630,641,703,720,774,818,1069,1094,1170,1217,1244,1370,1379 'htmx':3,9,30,44,50,54,67,71,90,143,169,179,261,307,327,421,439,521,531,547,558,600,776,790,801,814,832,968,977,995,1038,1072,1105,1110,1152,1166,1168,1186,1193,1204,1225,1266,1292,1427,1452 'htmx-awar':168 'htmx-driven':1265 'htmx-power':29 'htmx-specif':70 'htmx-target':142,306,1071,1203 'htmx.min.js':1156 'htmx.org':105,837,1465,1468,1471 'htmx.org/docs/':104,1464 'htmx.org/migration-guide-htmx-1/':1470 'htmx.org/reference/':836,1467 'htmxplugin':11,57,263,269,1054,1196 'htmxrequest':12,58,161,162,181,189,843,847,858,1063,1294,1324 'htmxtemplat':13,63,270,502,752,764 'hx':17,91,195,208,215,221,227,233,241,247,339,342,347,356,366,374,387,392,399,404,411,486,572,582,604,887,890,1005,1022,1026,1083,1174,1180,1247,1330,1405,1417 'hx-boost':226 'hx-current-url':232 'hx-ext':571,581 'hx-get':886,1082,1329 'hx-locat':410 'hx-post':889 'hx-prompt':240,246 'hx-push-url':373 'hx-redirect':355 'hx-refresh':365 'hx-request':194,1004,1021,1179,1246,1404 'hx-reswap':386 'hx-retarget':398 'hx-swap':391,603,1173 'hx-swap-oob':485 'hx-target':207,403,1025 'hx-trigger':214,338,1416 'hx-trigger-after-settl':346 'hx-trigger-after-swap':341 'hx-trigger-nam':220 'hxlocat':16,79,406 'hxstoppol':418 'i/o':130 'id':460,1364 'import':10,126,175,180,257,262,281,285,440,1282,1288,1293 'includ':991,1113,1376 'index':1304,1420 'inherit':719 'initi':1333 'input':244 'integr':1045,1424 'interpol':684 'item':187,292,294,303,304,319,321,447,451,648,710,1029,1261,1307,1314,1315,1338,1345,1346,1355,1381,1383,1392 'item-list':1028 'item.id':461,660,1365 'item.name':322,463,1367,1384 'item_service.create':453,1357 'item_service.list':296,1309,1340 'itemcontrol':1297 'itemcr':449,458,1353,1362,1413 'iter':651 'jinja':274,800,1453 'jinja-htmx':799 'jinja2':147,912,1208 'js':685,771,1133,1239 'js/css':535,1429 'json':594,606,613,626,654,698,746,769,782,1164,1171,1400 'keep':1134 'key':659,662 'layout':874,1079 'let':623,785 'level':1058 'lifecycl':1049 'like':900 'list':186,291,664,1030,1320 'litestar':2,8,20,32,43,45,53,86,99,119,174,178,256,258,260,265,280,438,505,526,540,550,574,584,805,849,954,972,986,1037,1047,1088,1142,1192,1201,1254,1281,1291,1422,1432,1440,1442,1449,1480 'litestar-bound':98 'litestar-htmx':1,42 'litestar-specif':85 'litestar-vit':525,539,804,953,971,1141,1253,1421,1431,1448 'litestar.response':284,1287 'litestar.testing.asynctestclient':1001 'load':704,727,819,1334 'locat':412 'logic':945,1135 'ls':617,646,658,667,675,681,749,786 'ls-els':674 'ls-for':645 'ls-if':666,680 'ls-key':657 'mako':149 'match':615 'may':122 'method':383 'middlewar':508,988,1220,1447 'mode':529,544,561,978,1256,1436 'modul':121 'mount':918 'multipl':478,481 'must':1112 'name':219,223,300,333,457,462,1361,1366,1401 'navig':417,827 'need':960,1147 'never':115,1075,1090 'new':396,491 'non':967,1108 'non-get':1107 'non-htmx':966 'none':114,212 'notif':492,1271 'object':74,330,1124,1213 'offici':1459 'one':795,875 'oob':466,488,1270 'openapi':1050 'option':116,956 'out-of-band':467 'outerhtml':384 'overrid':389,401 'page':140,203,796,862,870,922,1262 'pages/items.html':1312 'pair':523,951,1139 'param':336,459,1363 'pars':611 'parti':49 'partial':23,136,152,200,271,275,552,640,736,762,864,879,893,910,913,1011,1068,1243,1321,1326 'partial-html':639 'partials/item_list.html':301,1343,1377 'pass':844 'path':899,1187,1299 'pattern':94,642,1042 'pep':110 'plugin':268,1044 'poll':423,822 'post':442,891,1285,1347 'power':31 'prefer':1118 'present':198 'principl':1478 'project':532 'prompt':242,248 'properti':171,712 'protect':1102 'prototyp':718 'pure':1151 'purpos':331,644 'push':370,375,937 'pushurl':15,78,369 'put':943 'python':172,254,278,436,1015,1278,1386 'quick':159,816 'rather':1128 'raw':697,1216 'receiv':335,465,1369 'reconcili':665 'redirect':352,357,362,407 'refer':101,160,834,1419,1439,1460 'references/litestar_vite.md':1425 'refresh':367,817,933,1276 'region':479 'regist':1053,1198 'render':480,595,625,670,702,711,742,787,877 'replac':823 'request':60,165,188,196,238,845,857,1006,1023,1111,1181,1248,1323,1406 'request-sid':59 'request.htmx':191,780,905 'request.htmx.boosted':225 'request.htmx.current':230 'request.htmx.history':236 'request.htmx.prompt':239 'request.htmx.target':206 'request.htmx.trigger':213,218 'resources/main.js':566 'resp':1016,1396 'resp.headers':1415 'resp.status':1409 'resp.text':1034 'respons':25,65,73,328,329,475,608,628,655,699,1012,1089,1123,1212 'restor':237 'reswap':76,382,388,934,1126,1233 'retarget':77,394,400,935,1127,1234 'return':135,199,273,297,419,455,494,551,781,872,881,1067,1076,1163,1207,1310,1341,1359 'risk':1096 'rout':266,868,871,880,894,1074,1206 'rule':109 'save':435,490 'see':553,835,979,1013 'self':1305,1322,1351 'semant':1176 'sensit':757 'separ':924 'serv':767 'server':37,325,633,734,761,928,941,1121,1138,1228,1274 'server-driven':324,927,1120,1227 'server-sid':632,733 'server-trigg':36,1273 'set':337,354,364,372,385,397,409 'settl':350 'shape':740 'share':1474 'shouldn':1060 'side':61,360,415,577,593,634,735,810,812 'simpl':741 'singl':474,709 'single-item':708 'skill':83 'skill-litestar-htmx' 'soft':416 'source-litestar-org' 'specif':72,87 'stabl':661 'step':840,859,906,925,949,981,997 'stop':422 'str':211 'string':156,1092,1218 'string-concat':155,1091 'style':108 'styleguid':1475 'sub':898 'sub-path':897 'subclass':166 'success':434 'support':51 'swap':345,393,471,487,601,605,1175 'tag':516,597,621,724 'target':144,209,308,395,405,1027,1073,1085,1205 'task':1260 'templat':21,34,64,150,286,293,298,299,311,500,513,528,543,560,578,635,750,876,908,923,975,1087,1098,1211,1258,1289,1306,1311,1325,1342,1435,1444 'template-mod':559 'test':999,1177,1240,1390 'tests/test_items.py':1387 'text':688 'titl':721 'token':511,993,1116,1222 'topic-advanced-alchemy' 'topic-agent-skills' 'topic-agentskills' 'topic-ai-agents' 'topic-claude-code-plugin' 'topic-claude-code-skills' 'topic-gemini-cli-extension' 'topic-htmx' 'topic-inertia' 'topic-litestar' 'topic-mcp' 'topic-python' 'trigger':38,216,222,340,343,348,428,1275,1393,1418 'triggerev':14,75,332,441,450,456,932,1125,1232,1295,1354,1360 'trivial':743 'true':192,368,1007,1024,1182,1249,1407 'truthi':673 'type':855 'type-annot':854 'ul':1032 'union':112 'unlock':590 'updat':477 'url':231,235,371,376 'use':26,123,146,484,504,538,602,730,884,931,1000,1036,1086,1119,1214,1231,1252,1327 'user':243 'usual':990 'valid':1188 'verifi':1195 'via':520,596,717,763,994,1224 'vite':527,541,545,563,565,806,955,973,1143,1160,1255,1423,1433,1450,1456 'vite-bundl':1455 'vs':732,863 'widget':1402 'wire':249,842 'without':631,1159 'work':1157 'workflow':839 'xss':1095 'year':723","prices":[{"id":"128b2d41-9da8-46af-9519-9882bad851bd","listingId":"af64b697-b2cb-4ae1-a060-61b9c427937c","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"litestar-org","category":"litestar-skills","install_from":"skills.sh"},"createdAt":"2026-05-18T13:20:57.589Z"}],"sources":[{"listingId":"af64b697-b2cb-4ae1-a060-61b9c427937c","source":"github","sourceId":"litestar-org/litestar-skills/litestar-htmx","sourceUrl":"https://github.com/litestar-org/litestar-skills/tree/main/skills/litestar-htmx","isPrimary":false,"firstSeenAt":"2026-05-18T13:20:57.589Z","lastSeenAt":"2026-05-18T19:13:54.042Z"}],"details":{"listingId":"af64b697-b2cb-4ae1-a060-61b9c427937c","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"litestar-org","slug":"litestar-htmx","github":{"repo":"litestar-org/litestar-skills","stars":7,"topics":["advanced-alchemy","agent-skills","agentskills","ai-agents","claude-code-plugin","claude-code-skills","gemini-cli-extension","htmx","inertia","litestar","mcp","python","sqlspec"],"license":"mit","html_url":"https://github.com/litestar-org/litestar-skills","pushed_at":"2026-05-13T16:04:09Z","description":"Opinionated first-party agent skills, plugins, subagents, slash commands, and MCP servers for the Litestar framework ecosystem — publishable to Claude Code, Gemini CLI, Codex CLI, Cursor, OpenCode, and VS Code/Copilot from a single repo.","skill_md_sha":"68ebf967f620fa4c649ed36fb04656cf58e1b45b","skill_md_path":"skills/litestar-htmx/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/litestar-org/litestar-skills/tree/main/skills/litestar-htmx"},"layout":"multi","source":"github","category":"litestar-skills","frontmatter":{"name":"litestar-htmx","description":"Auto-activate for litestar_htmx imports, HTMXPlugin, HTMXRequest, HTMXTemplate, TriggerEvent, PushUrl, HXLocation, hx-* attributes in Litestar templates, or partial HTML responses. Use when building HTMX-powered Litestar handlers, templates, and server-triggered client events. Not for full SPA routing or non-Litestar HTMX apps."},"skills_sh_url":"https://skills.sh/litestar-org/litestar-skills/litestar-htmx"},"updatedAt":"2026-05-18T19:13:54.042Z"}}