フロントエンドの複雑さに疲れていませんか?
「簡単なCRUDアプリを作るだけなのに、なぜReactの環境構築が必要なんだ...」 「APIのエンドポイント設計と状態管理で消耗したくない...」
そんな開発者の救世主が HTMX です。 2024年6月にメジャーアップデートされた HTMX 2.0 は、Web Componentsサポートの強化やAPIの整理が行われ、より堅牢で使いやすくなりました。
本記事では、HTMX 2.0 と Django を組み合わせて、JavaScriptを(ほぼ)書かずに、モダンでインタラクティブなWebアプリを構築する方法を解説します。
最短で課題解決する一冊
この記事の内容と高い親和性が確認できたベストマッチです。早めにチェックしておきましょう。
HTMX 2.0 の何が凄いのか?
HTMXの基本思想は 「HTMLそのものを拡張して、サーバーとの通信を行わせる」 ことです。
1. HTMLだけでAJAX
<!-- ボタンをクリックすると /clicked にPOSTリクエストを送り、
返ってきたHTMLで #parent-div を置換する -->
<button hx-post="/clicked" hx-target="#parent-div" hx-swap="outerHTML">
クリックしてね
</button>2. HTMX 2.0 の新機能と変更点
- Web Components対応強化: Shadow DOM内でもHTMXがスムーズに動作するようになりました。
- 拡張機能の分離:
hx-ws(WebSocket) やhx-sse(Server Sent Events) がコアから分離され、必要な機能だけを読み込むスタイルになりました。 - View Transitions API 対応: ブラウザネイティブのアニメーションを使って、SPAのような滑らかなページ遷移が実現できます。
さらに理解を深める参考書
関連記事と相性の良い実践ガイドです。手元に置いて反復しながら進めてみてください。
実践:Django × HTMX で「リアルタイム検索」を作る
Djangoのテンプレート機能とHTMXを組み合わせるだけで、インクリメンタルサーチ(文字入力と同時に検索)を実装してみましょう。
1. 準備
django-htmx パッケージを入れると便利ですが、今回はシンプルにCDNでHTMX 2.0を読み込みます。
base.html
<!DOCTYPE html>
<html>
<head>
<title>Django x HTMX 2.0</title>
<!-- HTMX 2.0 CDN -->
<script src="https://unpkg.com/htmx.org@2.0.0"></script>
</head>
<body>
<div class="container">
{% block content %}{% endblock %}
</div>
<!-- CSRFトークン対応(Djangoで必須) -->
<script>
document.body.addEventListener('htmx:configRequest', (event) => {
event.detail.headers['X-CSRFToken'] = '{{ csrf_token }}';
});
</script>
</body>
</html>2. ビュー (views.py)
HTMXからのリクエストかどうかを判定し、部分テンプレート(HTMLの断片)を返します。
from django.shortcuts import render
from .models import Product
def product_list(request):
query = request.GET.get('q', '')
if query:
products = Product.objects.filter(name__icontains=query)
else:
products = Product.objects.all()
# HTMXからのリクエストなら、リスト部分だけをレンダリングして返す
if request.headers.get('HX-Request'):
return render(request, 'partials/product_list_items.html', {'products': products})
# 通常アクセスなら全ページを返す
return render(request, 'product_list.html', {'products': products})3. テンプレート (product_list.html)
検索ボックスにHTMXの属性を追加します。
{% extends 'base.html' %}
{% block content %}
<h1>商品検索</h1>
<!--
hx-get: 入力があるたびに現在のURLにGETリクエスト
hx-trigger: キーアップ後500ms待ってから発火(連打防止)
hx-target: #search-results の中身を書き換える
-->
<input type="text"
name="q"
placeholder="検索..."
hx-get="{% url 'product_list' %}"
hx-trigger="keyup changed delay:500ms"
hx-target="#search-results">
<div id="search-results">
{% include 'partials/product_list_items.html' %}
</div>
{% endblock %}4. 部分テンプレート (partials/product_list_items.html)
更新されるリスト部分だけを切り出します。
<ul>
{% for product in products %}
<li>{{ product.name }} - ¥{{ product.price }}</li>
{% empty %}
<li>見つかりませんでした。</li>
{% endfor %}
</ul>たったこれだけで、JavaScriptを1行も書かずに(CSRF設定以外)、高速なリアルタイム検索が完成しました!
さらに理解を深める参考書
関連記事と相性の良い実践ガイドです。手元に置いて反復しながら進めてみてください。
さらに高度なテクニック:Morph置換
HTMX 2.0の目玉機能の一つが Morphing です。
通常の innerHTML 置換だと、入力フォームのフォーカスが外れたり、スクロール位置がリセットされたりします。
idiomorph などの拡張を使うと、DOMの差分だけを賢く更新(Morph)してくれます。
<!-- head内で拡張を読み込み -->
<script src="https://unpkg.com/idiomorph/dist/idiomorph-ext.min.js"></script>
<!-- hx-swap="morph" を指定 -->
<div hx-ext="morph" hx-swap="morph:outerHTML">
...更新されるコンテンツ...
</div>これにより、ReactのVirtual DOMのような滑らかな更新体験を、サーバーサイドレンダリングで実現できます。
さらに理解を深める参考書
関連記事と相性の良い実践ガイドです。手元に置いて反復しながら進めてみてください。
まとめ
Djangoエンジニアにとって、HTMXは「フロントエンドの複雑さ」から解放してくれる強力な武器です。 ReactやVueが必要な場面はもちろんありますが、管理画面や社内ツール、シンプルなCRUDアプリなら、Django + HTMXの方が圧倒的に開発効率が高いでしょう。
2025年は、あえて「SPAを作らない」という選択肢を持ってみませんか?
さらに理解を深める参考書
関連記事と相性の良い実践ガイドです。手元に置いて反復しながら進めてみてください。


