コンテンツにスキップ

HTML メール

トランザクションメールを、Hypermedia Components のテーマ — テーマビルダーで作った カスタムテーマを含む — に揃えられます。ランタイム依存はありません。 キットが生成するのはテーマ焼き込み済みのテンプレート断片です: トークン参照をリテラル値に解決(rem は px に変換)し、インライン style 属性に書き込みます。メールクライアントは外部 CSS を読まず、 var() / カスタムプロパティも落とすためです。

  • インラインスタイルが基盤。 色・背景・パディング・タイポグラフィは 要素ごとにインライン化され、転送や、<head> のスタイルを丸ごと落とす 「Gmail アプリで Google 以外(IMAP/POP)のアカウントを読む」ケースでも 生き残ります。
  • 埋め込み <style> パーシャルは強化専用: モバイル幅と hc-em-* クラス経由の prefers-color-scheme: dark オーバーライド。 Apple Mail / Outlook macOS は尊重し、Gmail は無視して独自の自動反転を 適用します。どのルールも失われて構いません。
  • テーブルレイアウト、600px コンテナrole="presentation" の骨格、 bulletproof ボタン。VML は不使用: Outlook(Word エンジン)では border-radius が角丸にならず直角になります — 許容された劣化です。
  • 生成ファイルの先頭にはマニフェストコメントが付き、core の バージョン・軸設定・生成時の設定を記録するので、テーマ変更後の 再生成が確実に行えます。

パッケージ同梱(デフォルトテーマ)

Section titled “パッケージ同梱(デフォルトテーマ)”

ビルトインの軸については生成作業は不要です: core パッケージが @hypermedia-components/core/email-artifacts/… 配下に焼成済み アーティファクトを同梱しています — ニュートラルランプごとに 1 テーマ (アクセントは default)、両フレーバーです:

email-artifacts/contract.json 機械可読の契約
email-artifacts/default-<neutral>/email-tokens.json
email-artifacts/default-<neutral>/<flavor>/hc-email.html
email-artifacts/default-<neutral>/<flavor>/hc-email-layout.html

(<neutral>: gray、slate、zinc、neutral、stone。<flavor>: thymeleaf、plain。)生成物をリポジトリにチェックインする代わりに、 パッケージ(または WebJar)から直接解決してください — 再生成の儀式は 不要になり、アーティファクトは依存している core のバージョンと常に 一致します。contract.json は各フラグメントの th:fragment 名と パラメータ一覧を持つので、ダウンストリームのガードは HTML への 正規表現ではなくデータに対して検証できます:

ターミナルウィンドウ
node -e "console.log(require('@hypermedia-components/core/email-artifacts/contract.json').fragments.map(f => f.name + '(' + f.params + ')').join('\n'))"

カスタムアクセント・カスタムトークン・テーマビルダーのエクスポートは 引き続き以下のフローを使います。

テーマビルダーで テーマ(ビルトインのアクセントでもフルカスタムテーマでも)を設定し、 Email templates タブに切り替えます:

  • hc-email.html — 全断片(ボタン、見出し、本文、リンク、区切り線、 バッジ、アラート、パネル、キー・バリューテーブル、フッター)。
  • hc-email-layout.html — ドキュメントシェル(プリヘッダー、中央寄せ 600px カード)。強化用 <style> パーシャルは <head> に焼き込み済み。
  • email-tokens.json — 解決済みのライト/ダークトークン値。後述の ランタイムテーマ切替の逃げ道用。

フレーバーは 2 種類: Thymeleaf(th:fragment シグネチャと th:text / th:href スロット付き)とプレーン HTML(同じマークアップ から Thymeleaf 属性を剥がしたもの — お使いのエンジンのスロット構文を 追記してください)。

同じ 3 ファイルは @hypermedia-components/cli からも生成でき、スクリプトや CI での再生成に向いています:

ターミナルウィンドウ
npx @hypermedia-components/cli email eject --color indigo --neutral slate
npx @hypermedia-components/cli email eject --tokens my-theme.json --flavor plain
npx @hypermedia-components/cli email list # 断片の一覧

--tokens はテーマビルダーの DTCG エクスポート(アクセントツリー またはフルテーマパッチ)を受け取ります。これでループが閉じます: テーマは一度ビジュアルに作り、トークンが変わるたびにメールテンプレートを 再現可能に再生成できます。ファイルは <dir>/email/ に書き込まれ、 --force なしで既存ファイルを上書きすることはありません。

2 ファイルを src/main/resources/templates/email/ に置きます。各断片は パラメータ付き th:fragment で、エスケープは th:text が行います。 メールテンプレートはこれらを組み合わせます:

templates/email/order-confirmed.html
<div th:fragment="content">
<div th:replace="~{email/hc-email :: hcHeading('ご注文ありがとうございます')}"></div>
<div th:replace="~{email/hc-email :: hcText(${customerName} + ' 様、ご注文が確定しました。')}"></div>
<div th:replace="~{email/hc-email :: hcKvTable(${orderSummary})}"></div>
<div th:replace="~{email/hc-email :: hcButton(${orderUrl}, '注文を確認する')}"></div>
<div th:replace="~{email/hc-email :: hcFooter('このメールに心当たりがない場合は破棄してください。')}"></div>
</div>

レイアウトで包み、処理済み HTML を MimeMessageHelper#setText(html, true) で送信します:

<div th:replace="~{email/hc-email-layout :: hcLayout(
'注文確認', 'ご注文が確定しました',
~{email/order-confirmed :: content})}"></div>

利用できる断片とパラメータはパッケージ内の断片ごとの契約文書 (@hypermedia-components/core/email/<name>/contract.md)に 記載されています。全体のパターンは Thymeleaf ガイドと 共通です。

その他のテンプレートエンジン

Section titled “その他のテンプレートエンジン”

プレーン HTML フレーバーをダウンロードしてください: スロット位置に プレースホルダの文言が入った、同じ焼き込み済みマークアップです。断片を お使いのエンジン(Freemarker、ERB、Razor など)にコピーし、 プレースホルダのテキストや URL をエンジンの補間に置き換えます — その際のエスケープは自前で行ってください。Thymeleaf なしでは誰も 代わりにやってくれません。

焼き込み値は「生成時にテーマが確定している」前提です。リクエスト時に テナントごとのテーマが変わる場合は、テナントごとに email-tokens.json を読み込み、そこからインラインスタイルを書きます:

<td th:style="'background-color:' + ${t['button-primary-bg']} + ';border-radius:6px;'">

意図的に冗長な書き方です — テナントで変わる部分(通常はボタンの アクセント)だけに使い、残りは焼き込みのままにしてください。

テンプレートは生成物です: テーマを変えたら再ダウンロードしてください (各ファイル先頭のマニフェストコメントが、何から生成されたかをあなた — またはチームメイト — に正確に伝えます)。hc.tokens.css と同じ扱いで、 コミットはしても手編集はしないでください。