htmxを使ってbuttonを押した際に別のページを表示する方法

はじめに

こんにちは、新卒2年目の岡崎です。今回は、htmxを使ってbuttonを押した際に別のページを表示する方法を紹介します。

環境

  • gradle
------------------------------------------------------------
Gradle 8.5
------------------------------------------------------------

Build time:   2023-11-29 14:08:57 UTC
Revision:     28aca86a7180baa17117e0e5ba01d8ea9feca598

Kotlin:       1.9.20
Groovy:       3.0.17
Ant:          Apache Ant(TM) version 1.10.13 compiled on January 4 2023
JVM:          21.0.2 (Amazon.com Inc. 21.0.2+13-LTS)
OS:           Mac OS X 12.3 aarch64
openjdk version "21.0.2" 2024-01-16 LTS
OpenJDK Runtime Environment Corretto-21.0.2.13.1 (build 21.0.2+13-LTS)
OpenJDK 64-Bit Server VM Corretto-21.0.2.13.1 (build 21.0.2+13-LTS, mixed mode, sharing)
  • Spring Boot
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v3.2.1)

今回は、htmxとBootstrapを使っているため、以下の依存関係をbuild.gradleに追加します。

implementation "org.webjars.npm:htmx.org:1.9.10"
runtimeOnly("org.webjars:bootstrap:5.3.3")

実装

まずは、エンドポイントを作成します。/demoからbuttonを押すと、/newDemoに遷移するようにするため、2つのエンドポイントを用意しました。

@Controller
@RequestMapping("/")
public class DemoController {
    @GetMapping("demo") 
    public String demo() {
        return "index";
    }

    @PostMapping("newDemo") 
    public String newDemo() {
        return "newDemo";
    }
}

次に、resources配下にHTMLファイルを作成します。

  • index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>HTMX Example</title>
    <script src="/webjars/htmx.org/1.9.10/dist/htmx.min.js"></script>
    <link rel="stylesheet" href="/webjars/bootstrap-icons/1.11.3/font/bootstrap-icons.css">
    <link rel="stylesheet" href="/webjars/bootstrap/5.3.3/css/bootstrap.min.css">
</head>
<body>
        <div class="container text-center mt-5">
        <div>demo 1</div>
        <button class="btn btn-primary"
                th:hx-post="@{/newDemo}"
                th:hx-push-url="true"
                hx-target="body"
        >
            投稿
        </button>
        </div>
</body>
</html>

  • newDemo.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>HTMX Example</title>
    <script src="/webjars/htmx.org/1.9.10/dist/htmx.min.js"></script>
    <link rel="stylesheet" href="/webjars/bootstrap/5.3.3/css/bootstrap.min.css">
</head>
<body>
    <div class="container text-center mt-5">
        <p>新しいページです</p>
    </div>
</body>
</html>

以下で各機能を解説します。

hx-target

この属性は、どの部分を更新するかを指定します。ここでは、画面全体を更新したいのでbodyを指定しています。

hx-target="body"

参考:

htmx.org

hx-get

指定したエンドポイントにアクセスし、現在のHTMLページの内容が入れ替わります。

hx-getのみでは、HTMLの内容だけが置き換わり、URLはそのままです。

        <button class="btn btn-primary"
                th:hx-get="@{/newDemo}"
                hx-target="body"
        >
            投稿
        </button>

以下の画像に、実際の挙動を示しました。

参考:

htmx.org

hx-push-url

hx-push-urltrueにすると、ページの遷移に合わせてURLを変更できます。また、ブラウザの履歴にも記録できます。

        <button class="btn btn-primary"
                th:hx-get="@{/newDemo}"
                th:hx-push-url="true"
                hx-target="body"
        >
            投稿
        </button>

以下のスクリーンショットで、実際の挙動を確認できます。buttonを押すと、遷移先のURLに変わりました。

ブラウザの履歴にも、遷移先のエンドポイントが追加されました。

参考:

htmx.org

最後に

今回は、htmxを使ってbuttonを押した際に別のページを表示する方法を紹介しました。少しでも参考になれば幸いです。

また、エキサイトではフロントエンジニア、バックエンドエンジニア、アプリエンジニアを随時募集しております。長期インターンも歓迎していますので、興味があれば連絡いただければと思います。

募集職種一覧はこちらになります。

www.wantedly.com