扩展
htmx 4 把「非核心但常用」的能力都做成扩展,随主包一起发布在 dist/ext/ 下,每个不过几 KB。v4 的一大简化:扩展注册为全局钩子,引入脚本即生效,不再需要 hx-ext 声明。
启用扩展
v4 只需在 htmx 之后引入扩展脚本,它便自行挂载到带相应属性的元素上:
<script src="https://cdn.jsdelivr.net/npm/htmx.org@4.0.0/dist/htmx.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/htmx.org@4.0.0/dist/ext/hx-sse.js"></script>
<!-- 表单直接 hx-post,序列化交给 json-enc 扩展 -->
<form hx-post="/api/thing">…</form>
<!-- 元素自带 hx-sse:connect,SSE 扩展自动接管 -->
<div hx-sse:connect="/clock" hx-sse:swap="tick">…</div>想收紧可加载哪些扩展?v4 提供白名单:在
<meta name='htmx-config'> 里配置 extensions,值为逗号分隔的注册名(如 sse, pending),只有列名的扩展能注册。注册名取自扩展内部——hx-sse.js 注册为 sse、htmx-2-compat.js 注册为 compat,未必等于文件名。内置扩展一览
v4 主包 dist/ext/ 目录自带下列扩展(选择器均以 v4 冒号命名规范书写):
实时与网络
| 扩展 | 一句话 |
|---|---|
hx-sse | 服务器推送事件:hx-sse:connect 建流、hx-sse:swap 按事件名换入、hx-sse:close 收流 |
hx-ws | 双向 WebSocket:hx-ws:connect 连通道,配合 hx-ws:send 收发 HTML |
hx-multipart | 分块上传与断点续传游标(v4 新增) |
hx-download | 把响应存为文件,附带进度与 hx-download 命名 |
视图与状态
| 扩展 | 一句话 |
|---|---|
hx-live | 声明式绑定 + 响应式引擎——v4 的重量级新成员,局部状态不再需要外挂框架 |
hx-pending | 乐观 UI:请求先换入临时内容、落定后再校正(v4 由旧 hx-optimistic 更名而来) |
hx-upsert | 按 id 插入或更新元素,列表去重合并利器 |
hx-targets | 按 HTTP 状态码分叉换入落点(承接旧 response-targets) |
hx-history-cache | 自定义历史缓存策略 |
hx-head | AJAX 换页时同步更新 <head> 里的标题与样式 |
hx-browser-indicator | 接管浏览器原生加载指示 |
表单与安全
| 扩展 | 一句话 |
|---|---|
hx-prompt | 恢复 v2 的 hx-prompt 弹窗输入行为 |
hx-csp | nonce、safe-eval 与 Trusted Types——内容安全策略加固(v4 由旧扩展更名而来) |
hx-ptag | 把片段直接挂到 <head> 等位置 |
hx-alpine-compat | 与 Alpine.js 的morph 兼容桥 |
hx-compat / htmx-2-compat | 迁移桥:让 v2 的属性与事件名在 v4 上继续工作(仅作过渡,非长久之计) |
实时双雄:ws 与 sse
实时性交给两件套:hx-ws 建立双向 WebSocket 通道;hx-sse 走服务器推送事件。v4 里它们的属性统一走冒号命名:
<div hx-ws:connect="/socket/feed">
<div id="feed" hx-ws:send="beforeend">…</div>
</div>
<!-- v4 SSE:不带事件名的消息自动换入本元素 -->
<div hx-sse:connect="/clock">…</div>
<!-- 带事件名的消息不再自动换,而是派发为 DOM 事件,用 hx-trigger 接住 -->
<div hx-sse:connect="/alert" hx-trigger="tick" hx-get="/inbox" hx-target="this">…</div>本站的 SSE 时钟(活的)
等待推送…
服务器每秒经
EventSource 推来一行 HTML,htmx 照单就换——推送也是超文本。断线会自动重连。
v4 精简了 SSE 语义:旧版 sse-swap 属性已移除。服务端每 1000ms 只写一行无名
data: <span>…</span>,扩展便自动换入连接元素——上面那块时钟正这么走着。若发带 event: 名的消息,它会变成 DOM 事件,交由 hx-trigger 处理。推送也是超文本。自定义扩展
v4 的扩展 API 从「回调式」改为「事件式」:用 htmx.registerExtension() 注册,钩子按 htmx_命名空间_动作 直接命名,请求上下文挂在 detail.ctx 上:
htmx.registerExtension("my-addon", {
init(api) { /* 拿到内部 API 备用 */ },
htmx_config_request(elt, detail) {
detail.ctx.request.headers["X-Tag"] = "my-addon"; // 改请求头
},
htmx_after_request(elt, detail) {
console.log("请求落幕", detail.ctx.request.action);
},
});旧
htmx.defineExtension 与 onEvent 回调式写法在 v4 已移除——迁移到 registerExtension + 具名事件钩子。第三方生态
hyperscript
与 htmx 同门的极简脚本语言,客户端事件处理写成散文;v4 下 hx-on 与原生 JS 亦足用
hx-live 内置化
过去靠 Alpine/hyperscript 撑的局部响应式,v4 已把声明式绑定收进官方 hx-live 扩展
Sortable / clipboard / icons
拖拽排序、复制到剪贴板、按状态换图标——官方扩展页一页列全
说得再多,不如亲手一试——下一章,本站服务器已备好十一件演示(含四件 v4 招牌新特性)。