HTML ファーストで始める View Transitions API(htmx 編)
前回は、HTML ファーストで始める View Transitions API 入門 を書きました。その中では、リロードを伴うページ遷移である「cross-document」における View Transitions API の利用方法を解説しました。
今回は「same-document」という、ページ遷移を伴わず同一 HTML ドキュメント内で DOM が更新されるケースを取り上げ、View Transitions API を htmx でどのように実装できるかを見ていきます。
same-document / cross-document の整理
View Transitions API では、適用されるシーンによって same-document と cross-document の 2 つのパターンに分けて考えることができます。この分類は SPA / MPA の違いではなく、ブラウザにとってページ遷移が発生したかどうか という観点で区別されます。
cross-document
cross-document は、異なる HTML ドキュメント間でページ遷移が発生するケースです。
<a href="...">による通常のページ遷移- ブラウザが新しい HTML を読み込む
- DOM はすべて再構築される
このような場合に、遷移前と遷移後のページ全体を対象として View Transition が適用されます。
@view-transition {
navigation: auto;
}
上記の指定を行うだけで、ページ遷移時に自動的なクロスフェードが有効になります。
same-document
same-document は、ページ遷移を伴わず、同一 HTML ドキュメント内で DOM が更新されるケースです。
- JavaScript による DOM 操作
- htmx による部分更新
- SPA における画面切り替え
などが該当します。この場合、HTML ドキュメント自体は切り替わらず、更新前後の DOM の差分に対して View Transition が適用されます。
違いの整理
| 項目 | cross-document | same-document |
|---|---|---|
| ページ遷移 | あり | なし |
| HTML ドキュメント | 切り替わる | 同一 |
| DOM の更新範囲 | 全体 | 一部 |
| 主なトリガー | <a href> | JavaScript / htmx |
| 主な用途 | MPA | 部分更新 / SPA 的 UI |
また、htmx は基本的に JavaScript を書かず、HTML の属性を記述するだけで実装できる点も大きな特徴です。そのため、View Transitions API と組み合わせた場合でも、JavaScript による遷移制御やアニメーション処理を意識することなく、same-document の画面更新に自然な動きを加えることができます。
本記事では、この「HTML フラグメントの差し替え」と「same-document View Transitions」を組み合わせた実装を通して、HTML ファーストな設計のまま UX を向上させる方法 を具体的に見ていきます。
demo
サンプルサイトでは、サブカラムに index.html と初期表示時の HTML ファイル名を表示しています。サブカラムを書き換えることなく、メインカラムのコンテンツのみが切り替わっていることを確認できます。また、ページ遷移後にブラウザをリロードすると、そのページの HTML ファイル名に変わる点も確認できるようにしています。

https://kazumich.com/demo/view-transition/3_htmx/index.html
https://github.com/kazumich/view-transition
github に公開されている 2_view-transition をベースに 3_htmx へ変更していく流れを、以降で解説していきます。
htmx を利用可能にする
htmx は、特別なビルド環境や設定を必要とせず、JavaScript ファイルを 1 つ読み込むだけで利用できます。既存の HTML に後から追加できる点も、大きな特徴です。
CDN から読み込む
まずは、<head> 内に、以下を書きます。
<script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.8/dist/htmx.js"></script>
これだけで、hx-get や hx-post などの htmx 用属性が有効になります。 JavaScript の初期化コードは不要です。 CDN からの読み込みは、検証や実験用途として手軽に試す場合 には便利ですが、実運用のサイトでは htmx をダウンロードし、自サーバーに配置して利用する ことをおすすめします。
View Transitions API の利用
次の設定を追加することで、JavaScript を個別に記述することなく、htmx による same-document 更新で View Transitions API を利用できるようになります。
<script>
htmx.config.globalViewTransitions = true;
</script>
一覧ページから詳細ページへの遷移を htmx 化する
View Transitions API の基本設定については、HTML ファーストで始める View Transitions API 入門 で解説していますので、ここでは htmx 化に関する変更点のみを見ていきます。
変更前
通常の一覧ページから詳細ページへのリンクは、次のようなシンプルな <a> タグになります。
<a href="entry-1.html">
この場合、リンククリック時にページ全体が再読み込みされ、cross-document のページ遷移が発生します。
変更後
これを htmx で same-document の部分更新に変更します。
<a href="entry-1.html"
hx-get="entry-1.html"
hx-target="#main-content"
hx-swap="innerHTML"
hx-select="#main-content"
hx-push-url="true"
>
entry-1.html 以外のリンクについて、同様に追記していきます。
各属性の役割
hx-getリンククリック時に、指定した URL へ HTTP GET リクエストを送信します。hx-targetサーバーから返された HTML を差し替える対象要素を指定します。 この例では#main-contentの中身だけが更新されます。hx-swap="innerHTML"対象要素の内側を、取得した HTML に置き換えます。hx-select取得した HTML 全体ではなく、その中から指定した要素だけを抜き出して使用します。 一覧ページと詳細ページで共通のレイアウトを使っている場合に有効です。hx-push-url="true"ブラウザの URL をリンク先の URL に更新し、履歴にも追加します。 これにより、戻る・進む操作や URL の共有が通常のページ遷移と同じ感覚で行えます。
この変更による挙動
- ページ全体はリロードされない
#main-contentのみが差し替わる- View Transitions API により、same-document の画面遷移としてアニメーションが適用される
つまり、HTML の構造を保ったまま、MPA の設計で SPA に近い体験を実現できます。
補足:href を残す理由
href 属性は削除せず、そのまま残しています。これにより、
- JavaScript が無効な環境でも通常のリンクとして機能する
- 検索エンジンやクローラにも正しく認識される
といった、HTML ファーストな設計 を維持できます。
詳細ページへの遷移も htmx 化する
パンくずリストのリンクから、一覧ページへ戻る動作も htmx 化します。
<a href="index.html"
hx-get="index.html"
hx-target="#main-content"
hx-swap="innerHTML"
hx-select="#main-content"
hx-push-url="true">ホーム</a>
ここで指定している属性の役割は、一覧ページから詳細ページへの遷移と同じです。そのため、個別の解説は省略します。
HTML ファーストな same-document 更新
htmx による画面更新は、ページ遷移を伴わない same-document の更新であり、HTML ファーストな設計と非常に相性が良いのが特徴です。そのため、サーバーから返す HTML はページ全体である必要はなく、表示に必要な部分だけを返す構成でも問題ありません。
このように、最初から部分的な HTML(HTML フラグメント)を返す設計であれば、hx-select を指定せずに、そのまま hx-target へ差し替えることができます。
<a href="entry-1.html"
hx-get="entry-1.html"
hx-target="#main-content"
hx-swap="innerHTML"
hx-push-url="true"
>
entry-1.html のファイルの中身を <div id="main-content"> 〜 </div> だけにしても動作しますので、よろしければ一度お試しください。
それでも hx-select を使っている理由
本記事のデモでは、各ページを 通常の HTML ファイルとしても成立させる ことを重視しています。そのため、一覧ページ・詳細ページともにページ全体の HTML を返しつつ、hx-select を使って表示に必要な部分だけを抜き出しています。
この構成により、
- JavaScript が無効な環境でも通常のページ遷移が可能
- リロード時にも正しいページが表示される
- htmx を外しても HTML として成立する
といった、HTML ファーストな設計 を維持できます。
まとめ
View Transitions API は、ページ遷移を伴う cross-document だけでなく、ページ遷移を伴わない same-document の更新にも適用できます。htmx を利用することで、JavaScript をほとんど書かずに、HTML の属性だけで same-document な画面更新を実装できる点は、大きな利点です。
same-document の更新では、ページ全体の HTML を返す必要はなく、表示に必要な部分だけの HTML(HTML フラグメント)を返す設計でも成立します。一方で、通常の HTML ファイルとしても成立させたい場合には、hx-select を使って表示部分を切り出す構成も有効です。
重要なのは、フレームワークありきで SPA 化するのではなく、HTML の構造とブラウザの挙動を前提に、必要な部分だけを same-document 化する という考え方です。
まずは cross-document の View Transitions API から始め、必要な箇所だけ htmx による same-document 更新を取り入れる。そのように段階的に導入することで、HTML ファーストな設計を保ったまま UX を向上させることができます。