htmx là gì: Xây web tương tác chỉ bằng HTML, không cần framework

htmx là gì?

htmx là gì là câu hỏi nhiều lập trình viên gặp khi nghe tới cách xây giao diện web hiện đại mà không cần framework JavaScript phức tạp. htmx là một thư viện JavaScript siêu nhỏ, cho phép bạn dùng HTML thuần kết hợp với các thuộc tính để gửi AJAX request, hoán đổi nội dung trang, và nhận sự kiện theo thời gian thực — tất cả chỉ bằng vài dòng thuộc tính viết ngay trong HTML.

Điểm đáng chú ý: htmx chỉ nặng khoảng 16kB khi nén (min.gz), không phụ thuộc thư việc nào khác, và giúp giảm khoảng 67% số dòng code so với React theo công bố của chính dự án.

Sơ đồ so sánh kiến trúc ứng dụng web năm 2004 render phía server với kiến trúc năm 2019 dùng framework phía client
Kiến trúc web thay đổi thế nào từ 2004 tới nay

Tại sao htmx ra đời?

Từ lâu, chúng ta quen với một sự bất tiện: chỉ thẻ <a> và <form> mới gọi được HTTP request, chỉ sự kiện click và submit mới kích hoạt được, chỉ GET và POST là khả dụng, và mỗi lần tương tác thường phải thay cả trang. htmx gỡ bỏ toàn bộ những ràng buộc đó để hoàn thiện HTML như một hệ siêu văn bản.

Triết lý của dự án rất rõ ràng: ở lớp trình duyệt chỉ cần phần tối thiểu JavaScript để trao đổi với máy chủ, còn lại giữ nguyên ở máy chủ nơi bạn đã có sẵn ngôn ngữ, framework và cơ sở dữ liệu.

Cách cài đặt htmx

Cách nhanh nhất là nhúng trực tiếp từ CDN, chỉ cần một thẻ script trong phần <head>:

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/htmx.min.js"></script>

Đây là ví dụ đầy đủ đầu tiên — một nút gửi POST bằng AJAX và tự thay thế chính nó bằng nội dung trả về:

<button hx-post="/clicked" hx-swap="outerHTML">Click Me</button>

Câu lệnh trên bảo htmx: “Khi người dùng click nút này, gửi một AJAX request tới /clicked, rồi thay toàn bộ nút bằng HTML trả về từ server.” Không cần viết hàm JavaScript nào.

Các thuộc tính cốt lõi của htmx

htmx mở rộng nguyên lý hypermedia bằng một bộ thuộc tính rất trực quan. Dưới đây là những thuộc tính bạn sẽ dùng nhiều nhất:

Thuộc tính Công dụng
hx-get Gửi HTTP GET request tới URL chỉ định
hx-post Gửi HTTP POST request
hx-put / hx-patch / hx-delete Các phương thức HTTP còn lại
hx-trigger Chọn sự kiện kích hoạt, mặc định là click
hx-target Chọn phần tử đích nhận nội dung mới
hx-swap Cách thay nội dung: innerHTML, outerHTML, beforebegin, afterend, delete
hx-swap-oob Hoán đổi phần tử ngoài vùng request (out of band)
hx-indicator Hiển thị trạng thái đang tải bằng CSS selector
hx-confirm Hiện hộp thoại xác nhận trước khi gửi
hx-push-url Đẩy URL mới vào lịch sử trình duyệt
hx-vals / hx-vars Gửi kèm giá trị động dạng JSON

Ví dụ kết hợp nhiều thuộc tính để điều khiển một nút hoàn chỉnh:

<button hx-post="/clicked"
        hx-trigger="click"
        hx-target="#parent-div"
        hx-swap="outerHTML">
  Click Me!
</button>
Bìa sách Hypermedia Systems xuất bản bởi Big Liang
Hypermedia Systems — tài liệu chính thức về cách xây dựng ứng dụng hypermedia-driven với htmx

Out of band swaps: cập nhật nhiều vùng trong một response

Tính năng hay nhất của htmx là khả năng thay thế phần tử ngoài vùng request. Trong HTML trả về, bạn đánh dấu phần tử cần thay bằng thuộc tính hx-swap-oob:

<div id="message" hx-swap-oob="true">Swap me directly!</div>

Ngay cả khi người dùng chỉ tương tác với một khu vực, phần tử #message ở đâu đó khác cũng được cập nhật. Nhờ đó, một response duy nhất có thể vừa thay nội dung chính vừa cập nhật thanh thông báo, badge đếm hàng, hay giỏ hàng.

htmx và trạng thái đang tải

Thay vì tự thêm class khi AJAX bắt đầu, htmx cho phép bạn chỉ định phần tử làm chỉ báo trực quan:

<div>
  <button hx-get="/click" hx-indicator="#indicator">Click Me!</button>
  <img id="indicator" class="htmx-indicator" src="/img/bars.svg">
</div>

Chỉ cần CSS cho lớp htmx-indicator là chỉ báo sẽ ẩn mặc định và tự hiện ra trong lúc request đang chạy. Cách tiếp cận này giúp giao diện không bị nhấp nháy khi chuyển trạng thái.

Lịch sử trình duyệt và điều hướng

Nếu muốn đẩy URL vào lịch sử trình duyệt để người dùng bấm nút Back hoạt động bình thường, chỉ cần thêm hx-push-url:

<a hx-get="/blog" hx-push-url="true">Blog</a>

htmx sẽ chụp lại trạng thái DOM hiện tại trước khi gửi request, nên khi quay lại trang, nội dung được khôi phục đúng như cũ.

Server-Sent Events và WebSocket tích hợp sẵn

htmx không chỉ làm một request rồi xong. Thư viện còn tích hợp hai công nghệ thời gian thực để cập nhật giao diện từ máy chủ:

  • Server-Sent Events (SSE) — máy chủ đẩy dữ liệu xuống trình duyệt qua kết nối HTTP thường. Dùng thuộc tính hx-sse="swap:/updates" ngay trên thẻ <div>, mỗi khi có sự kiện mới server gửi về, phần tử đó tự cập nhật.
  • WebSocket — thuộc tính hx-ws="connect:/room" kết nối socket và cập nhật nội dung khi có tin nhắn. Phù hợp với ứng dụng chat, dashboard theo dõi giá.

Cả hai đều chạy hoàn toàn phía máy chủ, phía trình duyệt chỉ cần vài dòng thuộc tính. Đây là lý do nhiều người chọn htmx cho các dashboard nội bộ và trang quản trị.

Sơ đồ minh hoạ cách server gửi HTML đã render sẵn thay vì gửi JSON để client tự dựng lại giao diện
Server gửi HTML hoàn chỉnh thay vì bắt client tự dựng lại từ JSON

So sánh htmx với React và Vue

Tiêu chí htmx React / Vue
Kích thước thư viện Khoảng 16kB gzip, không dependency Hàng trăm kB tới vài MB kèm toolchain
Trạng thái ứng dụng Không cần, HTML từ server là nguồn sự thật Client-side store là nguồn sự thật
Render lần đầu Server gửi HTML hoàn chỉnh Render client rồi hydrate lần hai
Phù hợp nhất với Trang nội dung, form, admin panel, SSR Ứng dụng tương tác nặng như dashboard realtime phức tạp
Đường cong học Học HTML là xong Cần nắm JSX, hook, state, bundler

Điểm mấu chốt: htmx không cạnh tranh với React ở cùng một sân chơi. Nó giải quyết một câu hỏi khác — phần lớn website không cần một ứng dụng single-page. Với những trang như blog, trang bán hàng, hệ thống quản trị, một thư viện 16kB kèm logic ở server là đủ và đơn giản hơn nhiều.

Khi nào nên chọn htmx

htmx rất phù hợp khi bạn muốn nhanh chóng thêm tương tác vào một trang vốn đã render ở server, hoặc khi logic nghiệp vụ phức tạp đã nằm sẵn ở Python, Go, PHP hay Ruby và bạn không muốn dựng thêm một frontend riêng. Những trang CRUD, dashboard nội bộ, form nhiều bước, hay ứng dụng cần cập nhật thời gian thực đều là những ứng viên tốt.

Ngược lại, nếu bạn đang xây một trình soạn thảo văn bản trực tuyến, một bản đồ tương tác phức tạp, hay một ứng dụng offline-first, hãy vẫn dùng framework đầy đủ. htmx cũng chạy tốt nhất khi bạn còn giữ được một backend bằng ngôn ngữ bạn thành thạo.

Kết luận

htmx chứng minh rằng phần lớn sự phức tạp trong lập trình web frontend đến từ việc cố kéo logic ra khỏi máy chủ. Khi bạn đặt nguồn sự thật về phía HTML và server, bài toán trở nên đơn giản hơn rất nhiều: không state, không hydration, không bundler phức tạp — và tốc độ phát triển lại nhanh hơn.

Bạn có thể tham khảo tài liệu chính thức của dự án tại htmx.org/docs, hoặc đọc cuốn sách Hypermedia Systems để hiểu sâu hơn về cách xây dựng ứng dụng dựa trên hypermedia. Đồng thời hãy theo dõi four.htmx.org để nắm diễn biến của dòng htmx 4.x.

Tôi là một lập trình viên IOS. Code chính là IOS nhưng thỉnnh thoảng vẫn đá sang Android hoặc web. Mặc dù không quá thông thạo nhưng tôi sẽ chia sẻ những kiến thức mà mình đã tìm hiểu, áp dụng qua.

Bài viết liên quan

Cây AVL là gì: Cấu trúc dữ liệu tự cân bằng cho lập trình viên

Cây AVL là một dạng cây tìm kiếm nhị phân tự cân bằng, được phát minh bởi Georgy Adelson-Velsky và Evgenii Landis vào năm 1962. Cây AVL đảm bảo độ…

Xem thêm
Man hinh hien thi ma nguon JavaScript

Bun là gì: Runtime JavaScript nhanh tích hợp TypeScript

Bun là gì? Bun là một runtime JavaScript all-in-one được thiết kế để thay thế Node.js, nổi bật với tốc độ khởi động cực nhanh, tích hợp sẵn TypeScript, bundler…

Xem thêm

Rust là gì: Ngôn ngữ quản lý bộ nhớ an toàn không cần GC

Rust là một ngôn ngữ lập trình hệ thống nổi tiếng nhờ khả năng quản lý bộ nhớ an toàn mà không cần garbage collector. Bài viết này giải thích…

Xem thêm
0 0 đánh giá
Article Rating
Theo dõi
Thông báo của
guest
0 Comments
Cũ nhất
Mới nhất Được bỏ phiếu nhiều nhất