htmx 4.0 完整教學:什麼是 htmx?4.9 萬星、16KB 零依賴的 HTML 互動神器,從核心屬性到 morph swap 實戰(2026)

htmx 是用 HTML 屬性直接操控 AJAX、WebSocket 與 Server-Sent Events 的前端函式庫,16KB 零依賴、GitHub 4.9 萬星,官方宣稱可減少 67% 程式碼。本文從零教學:CDN 安裝、核心屬性總表、Flask 實戰範例,再到 2026 年 8 月發布的 htmx 4.0 三大變更(:inherited 顯式繼承、事件改名、fetch() 底層)與升級指南。

  • Dennis
  • 8 分鐘閱讀
htmx 4.0 完整教學:什麼是 htmx?4.9 萬星、16KB 零依賴的 HTML 互動神器,從核心屬性到 morph swap 實戰(2026)

htmx 是一個讓你在 HTML 屬性裡直接使用 AJAX、WebSocket 與 Server-Sent Events 的輕量函式庫:16KB、零依賴,用 hx-gethx-post 這類屬性就能讓任何元素發送 HTTP 請求並局部更新頁面——官方宣稱可減少 67% 的程式碼。

一句話結論

htmx 用屬性把「互動」寫回 HTML:不再需要 React 那套虛擬 DOM 與 JavaScript 狀態管理,伺服器回傳的 HTML 片段直接替換到指定位置,前端程式碼大幅減少,特別適合傳統後端工程師與不想碰 Node.js 建置鏈的團隊。2026 年 8 月 28 日發布的 htmx 4.0 在改進底層 fetch() 的同時,新增 morph swap 與 <hx-partial> 兩大功能。

htmx 是什麼?為什麼值得學?

htmx 的出發點是四個靈魂拷問:

  • 為什麼只有 <a><form> 能發 HTTP 請求?
  • 為什麼只有 click 和 submit 事件能觸發它們?
  • 為什麼只有 GET 和 POST 兩種方法?
  • 為什麼每次請求都只能替換整個頁面?

htmx 解除了這四個限制:任何元素都能發任何方法的請求、用任何事件觸發、並只替換指定區域——而這一切只需要在 HTML 上加屬性,不需要寫一行 JavaScript。這套哲學叫 Hypermedia-Driven Applications(HDA),是 2026 年對「SPA 萬能論」最有力的反擊。

特性htmxReact
檔案大小~16KB(min.gz)140KB+(含 ReactDOM)
依賴零依賴需建置鏈(Webpack/Vite)
學習曲線(學 HTML 屬性)高(JSX、hooks、狀態管理)
程式碼量官方宣稱減少 67%基準
渲染方式伺服器回傳 HTML 片段用戶端虛擬 DOM
適合場景傳統後端團隊、內容型網站、儀表板複雜互動應用、即時協作

截至 2026 年 8 月,htmx 在 GitHub 上有 4.9 萬顆星,作者是 Carson Gross(intercooler.js 的後繼者),並有專書《Hypermedia Systems》。

快速上手:60 秒寫出第一個互動按鈕

<!DOCTYPE html>
<html lang="zh-Hant">
<head>
  <meta charset="UTF-8">
  <!-- 4.0 版 CDN -->
  <script src="https://unpkg.com/htmx.org@4.0.0/dist/htmx.min.js"></script>
</head>
<body>
  <button hx-post="/clicked" hx-swap="outerHTML">
    點我!
  </button>
</body>
</html>

這段程式碼的意思:「當使用者點擊這個按鈕,用 AJAX 送 POST 到 /clicked,然後用伺服器回傳的 HTML 把整個按鈕換掉。」——沒有 addEventListener、沒有 fetch、沒有 state。

核心屬性總表(一次看懂 90% 的 htmx)

屬性功能範例
hx-get / hx-post / hx-put / hx-delete / hx-patch指定請求方法與 URLhx-get="/api/users"
hx-trigger觸發事件(click、change、submit、load、revealed、every 5s 輪詢、keyup changed delay:300ms 延遲輸入)hx-trigger="keyup changed delay:300ms"
hx-target更新哪個元素(CSS 選擇器,預設是自己;支援 closestfindnext 等擴展語法)hx-target="#result"
hx-swap怎麼替換(innerHTML、outerHTML、beforebegin、afterbegin、beforeend、afterend、none;4.0 新增 morphhx-swap="outerHTML"
hx-boost讓頁面內所有 <a><form> 都改成 AJAX 請求並自動更新 <title>hx-boost="true"
hx-push-url把請求 URL 推進瀏覽器歷史(支援上一頁)hx-push-url="true"
hx-confirm請求前彈出確認對話框hx-confirm="確定刪除?"
hx-indicator請求期間顯示載入動畫(指定元素,預設 class 是 htmx-indicatorhx-indicator="#loading"
hx-include一併送出其他表單欄位hx-include="#search-form"
hx-on用屬性寫事件監聽(替代 addEventListener)hx-on::after-request="alert('完成')"

htmx 運作原理

flowchart LR
    A[使用者觸發事件<br/>click / keyup / submit] --> B[htmx 攔截<br/>讀取 hx-* 屬性]
    B --> C[發送 AJAX 請求<br/>GET/POST/PUT/DELETE]
    C --> D[伺服器處理<br/>回傳 HTML 片段]
    D --> E[htmx 依 hx-swap 規則<br/>替換 hx-target 元素]
    E --> F[觸發 htmx:after:swap 事件<br/>CSS transition 動畫]

實戰:用 Flask 做一個即時搜尋框

htmx 最常被問的場景就是「搜尋框即時過濾」。完整程式如下:

前端 templates/index.html

<body>
  <h1>台灣縣市即時搜尋</h1>
  <input type="text" name="q" placeholder="輸入關鍵字..."
         hx-get="/search" hx-trigger="keyup changed delay:300ms"
         hx-target="#results" hx-swap="innerHTML">
  <div id="results">
    <!-- 伺服器回傳的結果會放這裡 -->
  </div>
</body>

後端 app.py

from flask import Flask, render_template_string, request

app = Flask(__name__)

CITIES = ["台北市", "新北市", "桃園市", "台中市", "台南市", "高雄市",
          "基隆市", "新竹市", "嘉義市", "新竹縣", "苗栗縣", "彰化縣"]

@app.get("/")
def index():
    return render_template_string(open("templates/index.html").read())

@app.get("/search")
def search():
    q = request.args.get("q", "").strip()
    # 伺服器回傳「純 HTML 片段」,不是 JSON!
    results = [c for c in CITIES if q in c]
    if not results:
        return "<p class='muted'>找不到符合的縣市</p>"
    return "".join(f"<li>{c}</li>" for c in results)

app.run(debug=True)

重點:伺服器回傳的是 HTML 片段而非 JSON,瀏覽器端完全不需要額外 JavaScript 處理——這就是 htmx「伺服器端渲染(SSR)天然支援」的威力,也是它跟 Fetch API 手動實作最大的差異。

htmx 4.0:2026 年 8 月 28 日發布的重大改版

htmx 4.0 歷經 8 個月開發,底層從 XMLHttpRequest 全面換成 fetch()。對一般使用者而言,外觀幾乎與 2.x 相同,但有三個主要變更:

1. 屬性繼承改為「顯式」——升級時最大的功課

htmx 2 的屬性繼承是隱式的:放在父元素的屬性會自動套用到子元素。4.0 改成必須明確加上 :inherited 後綴才會繼承:

<!-- htmx 2:隱式繼承 -->
<div hx-confirm="確定嗎?">
  <button hx-delete="/item/1">刪除</button>
</div>

<!-- htmx 4:顯式繼承 -->
<div hx-confirm:inherited="確定嗎?">
  <button hx-delete="/item/1">刪除</button>
</div>

官方提供了升級檢查工具,會自動標出需要加 :inherited 的位置:

npx htmx.org@4.0.0 upgrade-check -- ./templates

2. 事件名稱標準化:htmx:phase:action[:sub-action]

2.x 時代的事件名稱長得比較隨性(例如 htmx:beforeRequest),4.0 統一成 htmx:before:request 的格式:

htmx 2 舊名稱htmx 4 新名稱
htmx:beforeRequesthtmx:before:request
htmx:afterRequesthtmx:after:request
htmx:beforeSwaphtmx:before:swap
htmx:afterSwaphtmx:after:swap
htmx:configRequesthtmx:config:request

同時:大部分錯誤事件收斂成 htmx:error、HTTP 錯誤回應統一觸發 htmx:response:error、移除 htmx:xhr:*(因為改用 fetch)與 htmx:validation:*(改用瀏覽器原生表單驗證)。

3. History 不再依賴 localStorage

2.x 用 localStorage 快照頁面來支援「上一頁」,但第三方 JS 造成的 DOM 變更常讓還原後的頁面壞掉。4.0 改成返回時重新 fetch 頁面再 swap 進 <body>,第三方函式庫「開箱即用」;想要本地快取則改用官方新增的 hx-history-cache 擴充(sessionStorage 版)。

4.0 兩大新功能

  • Morph Swaphx-swap="morph" 內建 idiomorph 演算法,用「差異比對」的方式合併新舊 DOM——原本手動做「局部更新不閃爍」的苦工,現在一行屬性搞定。
  • <hx-partial> 標籤:一次請求更新多個區域的超清晰寫法:
<hx-partial hx-target="#messages" hx-swap="beforeend">
  <div>新訊息</div>
</hx-partial>
<hx-partial hx-target="#count">
  <span>5</span>
</hx-partial>

4.0 擴充生態系(大量新增)

擴充功能
hx-preload滑鼠懸停時預載內容,加速響應
hx-download原生 fetch 檔案下載
hx-alpine-compat與 Alpine.js 的相容層
hx-history-cachesessionStorage 歷史快取
hx-sse / hx-ws / hx-multipart串流 HTML(text/event-stream、WebSocket、multipart)
hx-live官方自家前端腳本方案(靈感來自 Alpine.js 與 hyperscript),支援 DOM-based、HATEOAS 友善的反應式寫法

懶得選的話,官方提供 htmax.js 單一 bundle,把 htmx 與最受歡迎的擴充打包成一包。官方也發布了 htmx-guidance、htmx-debugging、htmx-extension-authoring、htmx-upgrade-from-htmx2 四份 LLM skills,讓 AI 編程工具能正確開發與除錯 htmx 4。

htmx vs Alpine.js vs React:怎麼選?

面向htmx 4Alpine.jsReact
核心思維伺服器渲染的 HTML 片段用戶端輕量狀態繫結用戶端完整應用框架
主要工作位置伺服器端瀏覽器端瀏覽器端
寫法HTML 屬性(hx-*HTML 屬性(x-datax-textJSX + JavaScript
檔案大小~16KB~15KB140KB+
搭配後端任何語言(Flask/Django/Rails/Go…)任何需自建 API + 前端建置鏈
適合傳統網站、表單、儀表板、長青專案htmx 的補充(複雜 UI 狀態)重度互動的應用型產品

務實建議:內容型網站、內部工具、管理後台用 htmx;htmx 不好處理的複雜元件(拖放、巢狀狀態)用 Alpine.js 補;只有在產品核心本身就是「高互動應用」時才值得上 React。很多人是 htmx + Alpine.js 混用,互不衝突。

常見問題

Q:htmx 4.0 是破壞性升級嗎?會強制更新嗎? 不會。官方刻意不把 4.0 標為 npm 的 latest(2.x 繼續維持 latest 直到 2027 年初),避免使用非版本化 CDN URL 的使用者被強制升級;htmx 2.x 也會無限期支援。但 4.0 是預設推薦版本。

Q:不用 Node.js 可以學 htmx 嗎? 完全可以——用 CDN 引入即可,這是 htmx 最大的優勢之一,也是它能跟任何後端語言搭配的原因。

Q:htmx 對 SEO 友善嗎? 非常友善。內容預設就是伺服器端渲染的 HTML,搜尋引擎爬蟲直接讀得到;hx-boost 也保留真實的 <a href> 連結,跟無頭架構的 SPA 做法相比,少了大量 SEO 額外工程。

延伸閱讀

資料來源htmx 4.0.0 官方發布公告htmx 官方網站htmx GitHub Repository(4.9 萬星)Hypermedia Systems 官方書籍htmx 官方文件

📬 訂閱 most.tw 電子報

每週精選 AI 工具教學與技術乾貨,直接送到你的信箱。免費、隨時可退訂。

💬 有問題想討論?加 LINE 聯絡我

歡迎透過 LINE 官方帳號直接留言,我會盡快回覆你的問題。

加入 LINE 好友