Webアプリケーションを開発する際の肝になるのがサーバーサイドとの通信でしょう。クライアントサイドにはないデータを扱ったり、セキュリティ上データベースにあるデータにアクセスする際には、クライアント/サーバー間の通信が欠かせません。
しかし、その実装としてAjaxやfetch APIを使うのは面倒です。特に、HTMLテンプレートを使っている場合、サーバーサイドと通信するためにJavaScriptでDOMを操作する必要があります。
そこで紹介したいのがHMPL.jsです。簡易的なサーバーとの通信であれば、JavaScript不要で実装できるライブラリです。
HMPL.jsとは
HMPL.jsはサーバーとの通信を隠蔽してくれる、クライアントサイドで使えるテンプレート言語です。サーバーからはHTMLを返却し、受け取った結果をDOMの中に描画します。
HMPL.jsの基本
HMPL.jsでは、テンプレートとして .hmpl
という拡張子のファイルを利用します。たとえば、以下のような内容です。以下の場合、 GET /api/test
というリクエストを投げ、結果を <div />
タグの中に描画します。
<div>
<div
>
{{#request
src="/api/test"
method="get"
interval=1000
indicators=[
{
trigger: "pending",
content: "<p>Loading...</p>"
},
{
trigger: "rejected",
content: "<p>Error</p><button>reload</button>"
}
]
allowedContentTypes=["text/html"]
disallowedTags=["script", "style", "iframe"]
sanitize=false
}}{{/request}}
</div>
</div>
HMPL.jsの始め方
HMPL.jsは npm
ではじめられます。現状(2025年5月現在)だと、テンプレートに少し不具合があるようなので注意してください。
npx degit hmpl-language/hello-hmpl-starter hello-hmpl
cd hello-hmpl
npm install
npm run dev
これで、viteの開発環境が整います。ブラウザからは http://localhost:5173/
にアクセスすれば、HTMLが表示されます。

内容について
最初に表示されるのは src/HelloWorld.hmpl
の内容です。内容は上記のテンプレートの通りです。このファイルを main.js
で読み込んで表示しています。
import helloWorldTemplate from "./hmpl/HelloWorld.hmpl";
const { response: helloWorld } = helloWorldTemplate();
document.body.appendChild(helloWorld);
viteを使わない場合は、以下のようになります。この場合は、 GET /api/test
の結果を、 #wrapper
というIDの要素に描画します。
<div id="wrapper"></div>
<script src="https://unpkg.com/json5/dist/index.min.js"></script>
<script src="https://unpkg.com/dompurify/dist/purify.min.js"></script>
<script src="https://unpkg.com/hmpl-js/dist/hmpl.min.js"></script>
<script>
const templateFn = hmpl.compile(
`<div>
{{#request src="http://localhost:5173/api/test"}}{{/request}}
</div>`
);
const wrapper = document.getElementById("wrapper");
const obj = templateFn();
wrapper.appendChild(obj.response);
</script>
入力を受け付ける
HTMLフォームから入力を受け付ける例です。 src/Form.hmpl
というファイルを作成します。ファイル名は任意です。これは #form
の submit
イベントをトリガーにして、 POST /api/hello
というAPIを叩きます。 autoBody=true
にすることで、フォームの内容を自動的にリクエストボディに追加します。
<div>
<form id="form" method="post" onsubmit="event.preventDefault()">
<input type="text" name="name" placeholder="Enter your name" />
<input type="submit" value="Submit" />
</form>
<div>
{{#request
src="/api/hello"
after="submit:#form"
method="post"
autoBody=true
repeat=false
indicators=[
{
trigger: "pending",
content: "<p>Loading...</p>"
},
{
trigger: "rejected",
content: "<p>Error!</p>;"
}
]
}}
{{/request}}
</div>
</div>
このファイルを main.js
で読み込みます。
import helloWorldTemplate from "./hmpl/HelloWorld.hmpl";
import formTemplate from "./hmpl/Form.hmpl";
const { response: helloWorld } = helloWorldTemplate();
const { response: formEl } = formTemplate();
document.body.appendChild(helloWorld);
document.body.appendChild(formEl);
そして、 mock/api.js
を修正します。このファイルは、セットアップ時に生成されるファイルです。 export default
でエクスポートされている配列に、APIの情報を追加します。以下のように修正してください。これは POST /api/hello
というAPIで、受け取った name
を表示したHTMLを返却します。
export default [
// 以下を追加
{
url: "/api/hello",
method: "post",
rawResponse: async (req, res) => {
upload.any()(req, res, () => {
res.setHeader('Content-Type', 'text/html');
res.statusCode = 200;
res.end(<h2>Hello, ${req.body.name}</h2>
);
});
},
},
];

繰り返しアクセスする
以下のように interval=1000
を指定してテンプレートを作成すると、1000ミリ秒毎にサーバーへ定期的にアクセスします。
<div>
<div
>
{{#request
src="/api/test"
method="get"
interval=1000
indicators=[
{
trigger: "pending",
content: "<p>Loading...</p>"
},
{
trigger: "rejected",
content: "<p>Error</p><button>reload</button>"
}
]
allowedContentTypes=["text/html"]
disallowedTags=["script", "style", "iframe"]
sanitize=false
}}{{/request}}
</div>
</div>
以下は1秒毎に、現在時刻を返却するAPIにアクセスしている例です。

Tips
HMPL.jsには専用のVS Code機能拡張があります。これをインストールすると、HMPLのハイライトが有効になります。開発する際にはインストールすると便利です。
HMPL.jsでは、サーバー側はHTMLを返却する必要があります。JSONや、文字列ではうまく動かないので注意してください。たとえば Hello, Monaca!
ではなく、 <div>Hello, Monaca!</div>
のようにHTMLを返却する必要があります。
まとめ
HMPL.jsは、クライアントとサーバーサイドの連携を手軽に実装できるライブラリです。複雑なWebアプリケーションには向かないかも知れませんが、ちょっとしたデータ取得であれば十分使えそうです。特に、プログラミング初学者であれば便利に使えるでしょう。
HTMLでレスポンスを返さないといけないなど、癖もありますが、便利に使える場面もありそうなので覚えておくと良いでしょう。