Thymeleaf javascript 連携のサンプルコード解説
新人
「先輩、ThymeleafでサーバーからJavaScriptにデータを渡すことってできるんですか?」
先輩
「もちろんできるよ。ThymeleafはサーバーサイドでHTMLを動的に生成するテンプレートエンジンだから、Controllerで用意した値をテンプレート内のJavaScriptに埋め込むことができるんだ。」
新人
「それなら、画面の表示内容をサーバーの値に合わせて変えることもできますね!」
先輩
「そういうこと。今回は、ThymeleafとJavaScriptを連携させて、ControllerからModel経由で値を渡す方法を実際のコードで見てみよう。」
1. ThymeleafとJavaScriptの連携とは?
Thymeleaf(タイムリーフ)はSpring Frameworkで広く使われるテンプレートエンジンです。サーバーサイドでHTMLを動的に生成することができるため、画面の内容をサーバー変数に応じて柔軟に変更できます。
ThymeleafとJavaScriptを連携させると、サーバーで用意した値をブラウザのスクリプト内で扱えるようになります。例えば、Controllerで設定したユーザー情報をJavaScriptの変数に埋め込み、動的に画面を切り替えることが可能になります。
Webアプリケーションでは、サーバー側で取得した値をJavaScriptに渡して、表示制御や入力チェックに利用するケースが多くあります。Thymeleafはth:inline="javascript"という専用の仕組みを持っており、これを使うことで安全にサーバー変数をJavaScriptへ渡すことができます。
このような仕組みを理解しておくと、サーバーとフロントエンドの橋渡しがスムーズになり、メンテナンス性の高いWebアプリを作ることができます。
ここでは、実際にControllerからModelを使って値を渡し、それをThymeleafテンプレートで表示する基本を見ていきましょう。
2. @ControllerからThymeleafへ値を渡す仕組み
SpringアプリケーションでThymeleafを使うときの基本は、ControllerクラスからModelを通じてデータをテンプレートに渡すことです。開発環境はpleiadesを使用し、依存関係はGradleで管理します。MavenではなくGradleを使うのが今回の前提です。
Thymeleafテンプレートに値を渡すControllerの基本構造を見てみましょう。
@Controller
public class SampleController {
@GetMapping("/sample")
public String showPage(Model model) {
model.addAttribute("userName", "花子");
model.addAttribute("userAge", 25);
return "sample";
}
}
この例では、@Controllerアノテーションを使ってクラスを定義し、@GetMappingでURLパス/sampleを指定しています。ModelオブジェクトにaddAttribute()メソッドでデータを登録し、それをsample.htmlというテンプレートに渡しています。
次に、Thymeleafテンプレート側でその値を表示してみましょう。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Thymeleaf JavaScript 連携の基本</title>
</head>
<body>
<h3 th:text="'ユーザー名:' + ${userName}"></h3>
<h3 th:text="'年齢:' + ${userAge} + '歳'"></h3>
</body>
</html>
このHTMLをブラウザで開くと、サーバー側の値が展開され、「ユーザー名:花子」「年齢:25歳」と表示されます。ThymeleafはサーバーでHTMLを生成するため、ブラウザにはすでに展開済みのHTMLが送られます。
つまり、クライアント側で特別な処理をしなくても、サーバーのデータがそのまま反映されるのが特徴です。ここでThymeleafとJavaScriptを組み合わせれば、サーバー変数をブラウザスクリプト内でも利用できるようになります。
例えば、この${userName}や${userAge}をJavaScriptに渡すことで、動的なメッセージ表示や条件分岐が実現できます。この連携が「Thymeleaf JavaScript 変数渡し」の基本です。
この仕組みを理解しておくと、サーバーからフロントエンドに安全に値を渡す設計ができるようになり、動的な画面制御やバリデーションにも応用できます。
次のステップでは、実際にThymeleafのth:inline="javascript"構文を使って、サーバー変数をJavaScriptで扱う方法を見ていきます。
3. ThymeleafからJavaScriptに値を埋め込む方法(th:inline="javascript" の使い方)
ここからは、Thymeleafでサーバーから渡された値をJavaScript内に埋め込む方法を見ていきましょう。Thymeleafでは、th:inline="javascript"を使うことで、JavaScriptコードの中に安全にサーバー変数を展開できます。
通常、HTML内のJavaScriptにサーバーの変数を埋め込むとき、単純に${変数}と書くと正しく展開されません。そのため、Thymeleafでは[[${変数}]]という特別な構文を使用します。
この構文を使うと、JavaScript内でThymeleafの変数を展開でき、スクリプト中に動的な値を反映させることが可能です。次のサンプルで実際の記述を見てみましょう。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Thymeleaf JavaScript 埋め込みサンプル</title>
</head>
<body>
<h3 th:text="'ユーザー名:' + ${userName}"></h3>
<h3 th:text="'年齢:' + ${userAge} + '歳'"></h3>
<script th:inline="javascript">
/*<![CDATA[*/
let name = [[${userName}]];
let age = [[${userAge}]];
console.log("ユーザー名:", name);
console.log("年齢:", age);
/*]]>*/
</script>
</body>
</html>
th:inline="javascript"を指定することで、ThymeleafがJavaScript内の[[ ]]構文を認識して、サーバーから渡された値に置き換えてくれます。実際にブラウザでページを表示すると、開発者ツールのコンソールに「ユーザー名: 花子」「年齢: 25」と出力されます。
ここで大事なのは、JavaScript内でThymeleafの変数を使うときは必ず[[ ]]を使うという点です。${ }のままでは、HTML上で評価されずにそのまま文字列として扱われてしまうため、正しく動作しません。
また、文字列を扱う場合は、Thymeleafが自動的にクォートを付けてくれますが、手動で囲ってしまうと二重クォートになってエラーの原因になります。次の章でこの点をさらに詳しく見ていきましょう。
4. JavaScript内でThymeleafの変数を使う際の注意点([[${変数}]]構文の仕組み)
ThymeleafでJavaScriptに値を埋め込む際、初心者がつまずきやすいのが「クォートの扱い」です。特に文字列変数を扱うとき、[[${変数}]]をそのまま使うのか、クォートで囲むのか迷う人が多いです。
実は、Thymeleafのth:inline="javascript"を設定していれば、文字列は自動的にJavaScript形式でエスケープされます。そのため、基本的に自分でクォートを付ける必要はありません。
たとえば次のようなコードを見てください。
<script th:inline="javascript">
/*<![CDATA[*/
let message = [[${welcomeMessage}]];
alert(message);
/*]]>*/
</script>
もしwelcomeMessageが「こんにちは、花子さん!」という文字列であれば、Thymeleafは自動的に次のように展開します。
let message = "こんにちは、花子さん!";
alert(message);
つまり、開発者がクォートを重ねて書くと、次のような誤ったコードになってしまいます。
let message = ""こんにちは、花子さん!"";
このような場合、ブラウザのコンソールで「Uncaught SyntaxError」といったエラーが発生します。初心者がよく見落とすポイントなので、注意しておきましょう。
逆に、数値や真偽値(boolean)の場合は、クォートが自動で付かないため、数値はそのまま使えます。Thymeleafはデータ型を判断して適切に出力してくれるのが特徴です。
また、th:inline="javascript"を付け忘れると、[[${変数}]]構文は機能せず、HTML上にそのまま「[[${userName}]]」という文字列が出てしまいます。これも初心者がよく遭遇するミスのひとつです。
この構文の仕組みを理解しておくことで、Controllerの値をJavaScriptに正しく受け渡し、動的な画面制御が行えるようになります。
5. 実際にControllerの値をJavaScriptで受け取って出力する例
ここでは、実際にControllerからThymeleaf経由でJavaScriptに値を渡し、ブラウザで動的に表示する流れをまとめてみましょう。
まず、Controllerでサーバーから値をModelに格納します。
@Controller
public class DemoController {
@GetMapping("/show")
public String showUser(Model model) {
model.addAttribute("userName", "太郎");
model.addAttribute("userAge", 30);
model.addAttribute("welcomeMessage", "ようこそ、Thymeleafの世界へ!");
return "show";
}
}
次に、Thymeleafテンプレート側でJavaScriptに変数を埋め込み、ブラウザのコンソールと画面に出力します。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Thymeleaf JavaScript 変数埋め込み</title>
</head>
<body>
<h2 th:text="${welcomeMessage}"></h2>
<script th:inline="javascript">
/*<![CDATA[*/
let userName = [[${userName}]];
let userAge = [[${userAge}]];
let message = [[${welcomeMessage}]];
console.log("ユーザー名:", userName);
console.log("年齢:", userAge);
console.log("メッセージ:", message);
document.body.insertAdjacentHTML("beforeend",
"<p>ユーザー:" + userName + "(" + userAge + "歳)</p>");
/*]]>*/
</script>
</body>
</html>
このサンプルを実行すると、ブラウザの画面上に「ユーザー:太郎(30歳)」と表示され、コンソールにも同じ内容が出力されます。サーバーで生成した値がクライアント側のJavaScriptに正しく渡っていることが確認できます。
このように、Thymeleafのth:inline="javascript"を活用すれば、ControllerからModelを通じて送られた値をJavaScriptで利用できるようになります。フォーム入力の初期値設定や、サーバー情報をもとにした動的な処理など、さまざまな場面で応用できるでしょう。
また、セキュリティ面でもThymeleafが自動でエスケープ処理を行ってくれるため、クロスサイトスクリプティング(XSS)のリスクを軽減できます。直接JavaScript内にサーバー値を埋め込む場合でも、安全な形で処理される点が大きなメリットです。
今回学んだように、Controller・Model・Thymeleaf・JavaScriptの連携を理解しておくと、Springアプリケーションでのフロントエンド開発がより柔軟になります。テンプレートエンジンを通じて、サーバーのデータとブラウザの動きを自然につなげる設計を意識していきましょう。
6. JavaScriptで条件分岐やイベント制御にThymeleaf変数を使う例
ここからは、Thymeleafで埋め込んだサーバー変数をJavaScriptの条件分岐やイベント制御で活用する方法を学びましょう。実際の業務でも、サーバーの値に応じてボタンを無効化したり、メッセージを切り替えたりする場面がよくあります。
例えば、Controllerでログイン状態を表すフラグをModelに渡し、JavaScriptでボタンの表示を切り替えるようにしてみましょう。
@Controller
public class UserController {
@GetMapping("/status")
public String showStatus(Model model) {
model.addAttribute("isLoggedIn", true);
model.addAttribute("userName", "佐藤");
return "status";
}
}
次に、Thymeleafテンプレートでこの値をJavaScriptに埋め込みます。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Thymeleaf 条件分岐の例</title>
</head>
<body>
<button id="loginBtn">ログイン</button>
<button id="logoutBtn">ログアウト</button>
<script th:inline="javascript">
/*<![CDATA[*/
let isLoggedIn = [[${isLoggedIn}]];
let userName = [[${userName}]];
if (isLoggedIn) {
document.getElementById("loginBtn").style.display = "none";
document.getElementById("logoutBtn").style.display = "inline";
console.log(userName + "さんがログイン中です");
} else {
document.getElementById("loginBtn").style.display = "inline";
document.getElementById("logoutBtn").style.display = "none";
console.log("未ログイン状態です");
}
document.getElementById("logoutBtn").addEventListener("click", function() {
alert(userName + "さん、ログアウトしました!");
});
/*]]>*/
</script>
</body>
</html>
この例では、Thymeleafの変数[[${isLoggedIn}]]を条件分岐に使っています。サーバーでtrueが渡された場合、ログインボタンが非表示になり、ログアウトボタンが表示されます。ユーザー名も[[${userName}]]から取得し、イベントで利用しています。
このように、サーバーから受け取った値をJavaScriptのロジックに直接反映させることで、動的な画面制御が可能になります。フロント側の条件判定にThymeleaf変数を使うのは、実務でもよくあるパターンです。
7. JSON形式のデータを渡す応用(MapやDTOをJavaScriptで扱う方法)
続いて、Thymeleafを使ってJSON形式のデータをJavaScriptに渡す方法を紹介します。実務では、単一の変数だけでなく、複数の値をまとめたMapやDTOを扱うケースも多いです。
Controllerで複数のユーザー情報をMapとしてModelに格納し、ThymeleafでJSONに変換してJavaScriptに渡してみましょう。
@Controller
public class JsonController {
@GetMapping("/users")
public String showUsers(Model model) {
Map<String, Object> user = new HashMap<>();
user.put("name", "山田");
user.put("age", 28);
user.put("email", "yamada@example.com");
model.addAttribute("userMap", user);
return "users";
}
}
ThymeleafテンプレートでこのMapをJSONとして扱うには、th:inline="javascript"を利用してJavaScriptのオブジェクトに展開します。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Thymeleaf JSON 連携</title>
</head>
<body>
<h2>ユーザー情報</h2>
<div id="info"></div>
<script th:inline="javascript">
/*<![CDATA[*/
let user = [[${userMap}]];
console.log("ユーザー情報:", user);
document.getElementById("info").innerHTML =
"名前:" + user.name + "<br>年齢:" + user.age + "<br>メール:" + user.email;
/*]]>*/
</script>
</body>
</html>
Thymeleafは、MapやDTOを自動的にJSONオブジェクトへ変換してくれます。JavaScriptからはuser.nameやuser.emailのようにアクセスできるため、API通信を使わずともサーバーデータを簡単に扱えます。
この方法は、Ajax通信の初期値設定や、画面初期描画のデータ埋め込みに非常に便利です。Springアプリの初期ロード時にサーバーの値を渡すことで、クライアント側のリクエスト数を減らせるというメリットもあります。
8. 実務で使えるThymeleafとJavaScript連携のベストプラクティス
最後に、ThymeleafとJavaScriptを組み合わせる際に知っておくと役立つベストプラクティスを紹介します。実務では、テンプレートを整理してメンテナンス性を保つことが重要です。
① th:inlineは必要な箇所に限定する
th:inline="javascript"を使うと便利ですが、すべてのスクリプトに付けると可読性が下がります。Thymeleafの変数を使う箇所のみに限定し、それ以外のJavaScriptは通常の外部ファイルとして分離しましょう。これによりHTMLの保守性が向上します。
② 複雑な処理は外部JSにまとめる
Controllerから渡す値をHTML側のスクリプトで受け取ったあと、実際の処理は外部JavaScriptに委譲するのが理想です。Thymeleafはあくまで初期値を渡す役割に留め、動的な操作やイベント処理は別ファイルに整理することで再利用性が高まります。
③ セキュリティに配慮する
Thymeleafは自動エスケープ機能を持っていますが、外部スクリプトを動的に生成する際にはXSS攻撃への注意が必要です。ユーザー入力を直接JavaScriptへ埋め込まないようにし、Controller側でサニタイズ(無害化)処理を行うことが大切です。
④ JSONデータを扱うときの注意点
MapやDTOをJavaScriptに渡す場合、Thymeleafが生成するJSONは構造が深くなることがあります。デバッグ時にはブラウザのコンソールでconsole.log()を活用し、オブジェクトの中身を確認しながら実装を進めるのがコツです。
⑤ 条件分岐のロジックはControllerで整理する
フロント側のJavaScriptで多くの条件を分岐するよりも、サーバー側であらかじめ状態を判定し、シンプルなフラグを渡す設計が推奨されます。例えば「isAdmin」や「hasPermission」といった真偽値を渡すことで、画面側のロジックを簡潔にできます。
⑥ 例:ユーザー権限によるボタン表示制御
次の例は、Thymeleafの変数をJavaScriptで受け取り、ユーザーの権限に応じてボタンの表示を切り替えるものです。
@Controller
public class RoleController {
@GetMapping("/role")
public String showRole(Model model) {
model.addAttribute("isAdmin", false);
model.addAttribute("userName", "田中");
return "role";
}
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Thymeleaf 条件付き表示</title>
</head>
<body>
<h2 th:text="'ようこそ、' + ${userName} + 'さん!'"></h2>
<button id="adminBtn">管理者設定</button>
<script th:inline="javascript">
/*<![CDATA[*/
let isAdmin = [[${isAdmin}]];
if (!isAdmin) {
document.getElementById("adminBtn").style.display = "none";
console.log("一般ユーザーには管理ボタンを非表示にします");
} else {
console.log("管理者権限が確認されました");
}
/*]]>*/
</script>
</body>
</html>
このように、Controller側でフラグを渡すことで、JavaScriptでは簡潔な条件分岐だけで済みます。テンプレートの可読性を保ちながら、Thymeleafの変数を効率的に活用できます。
以上のポイントを押さえれば、ThymeleafとJavaScriptの連携を安全かつ柔軟に行えるようになります。サーバーの値をうまく利用しながら、動的で使いやすいWebアプリを構築していきましょう。