react-email について
JSON 仕様を HTML またはプレーンテキストのメールに変換する React Email レンダラーです。サーバーサイド描画やブラウザーでのプレビューに加え、標準的なメールレイアウトとコンテンツ用コンポーネントを備えています。
主な機能
- 01仕様を HTML またはプレーンテキストに描画
- 02サーバーセーフなスキーマとカタログのインポート
- 03ブラウザーでの描画とプレビュー
- 04表示条件、状態、繰り返し式に対応
- 05標準的なメールレイアウトとコンテンツ用コンポーネント
活用シーン
- 01JSON 仕様からメールを生成
- 02ブラウザーでメールレイアウトをプレビュー
- 03状態に応じたメールコンテンツを描画
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ vercel-labs/ json-render --skill react-emailインストール後、Claude Code で/react-emailを入力して読み込まれたか確認します。
詳細
@json-render/react-email
JSON 仕様を HTML またはプレーンテキストのメール出力に変換する React Email レンダラーです。
クイックスタート
import { renderToHtml } from "@json-render/react-email";
import { schema, standardComponentDefinitions } from "@json-render/react-email";
import { defineCatalog } from "@json-render/core";
const catalog = defineCatalog(schema, {
components: standardComponentDefinitions,
});
const spec = {
root: "html-1",
elements: {
"html-1": { type: "Html", props: { lang: "en", dir: "ltr" }, children: ["head-1", "body-1"] },
"head-1": { type: "Head", props: {}, children: [] },
"body-1": {
type: "Body",
props: { style: { backgroundColor: "#f6f9fc" } },
children: ["container-1"],
},
"container-1": {
type: "Container",
props: { style: { maxWidth: "600px", margin: "0 auto", padding: "20px" } },
children: ["heading-1", "text-1"],
},
"heading-1": { type: "Heading", props: { text: "Welcome" }, children: [] },
"text-1": { type: "Text", props: { text: "Thanks for signing up." }, children: [] },
},
};
const html = await renderToHtml(spec);
仕様の構造(要素ツリー)
@json-render/react と同じフラットな要素ツリーです。root キーと elements マップで構成されます。ルートは Html である必要があります。Html の子要素には Head と Body を指定します。クライアントに安全なレイアウトにするには、Body 内で Container(例:最大幅 600px)を使用します。
カタログとレジストリの作成
import { defineCatalog } from "@json-render/core";
import { schema, defineRegistry, renderToHtml } from "@json-render/react-email";
import { standardComponentDefinitions } from "@json-render/react-email/catalog";
import { Container, Heading, Text } from "@react-email/components";
import { z } from "zod";
const catalog = defineCatalog(schema, {
components: {
...standardComponentDefinitions,
Alert: {
props: z.object({
message: z.string(),
variant: z.enum(["info", "success", "warning"]).nullable(),
}),
slots: [],
description: "A highlighted message block",
},
},
actions: {},
});
const { registry } = defineRegistry(catalog, {
components: {
Alert: ({ props }) => (
<Container style={{ padding: 16, backgroundColor: "#eff6ff", borderRadius: 8 }}>
<Text style={{ margin: 0 }}>{props.message}</Text>
</Container>
),
},
});
const html = await renderToHtml(spec, { registry });
サーバーサイドのレンダリング API
| 関数 | 用途 |
|---|---|
renderToHtml(spec, options?) | 仕様を HTML メール文字列にレンダリングします |
renderToPlainText(spec, options?) | 仕様をプレーンテキストのメール文字列にレンダリングします |
RenderOptions:registry、includeStandard(デフォルトは true)、state($state / $cond 用)。
表示条件と状態
visible 条件、$state、$cond、繰り返し(repeat.statePath)、{ "$item": "field" } を使ったネストされた繰り返しパス、および @json-render/react と同じ式構文をサポートしています。サーバーサイドでレンダリングする際は、式が解決されるように RenderOptions の state を使用してください。
サーバーセーフなインポート
React や @react-email/components を使わずに、スキーマとカタログをインポートします。
import { schema, standardComponentDefinitions } from "@json-render/react-email/server";
主なエクスポート
| エクスポート | 用途 |
|---|---|
defineRegistry | カタログから型安全なコンポーネントレジストリを作成します |
Renderer | ブラウザーで仕様をレンダリングします(例:プレビュー)。状態やアクションには JSONUIProvider と組み合わせて使用します |
createRenderer | 状態、アクション、検証を備えたスタンドアロンのレンダラーコンポーネントです |
renderToHtml | サーバー:仕様を HTML 文字列に変換します |
renderToPlainText | サーバー:仕様をプレーンテキスト文字列に変換します |
schema | メール要素のスキーマ |
standardComponents | 事前構築済みのコンポーネント実装 |
standardComponentDefinitions | カタログ定義(Zod props) |
サブパスのエクスポート
| パス | 用途 |
|---|---|
@json-render/react-email | パッケージ全体 |
@json-render/react-email/server | スキーマとカタログのみ(React なし) |
@json-render/react-email/catalog | 標準コンポーネントの定義と型 |
@json-render/react-email/render | レンダリング関数のみ |
標準コンポーネント
すべてのコンポーネントは、インラインスタイル用の style プロパティ(オブジェクト)を受け取ります。メールクライアントとの互換性を保つにはインラインスタイルを使用し、外部 CSS は避けてください。
ドキュメント構造
| コンポーネント | 説明 |
|---|---|
Html | ルートラッパー(lang、dir)。子要素:Head、Body。 |
Head | メールの head セクションです。 |
Body | body のラッパーです。背景には style を使用します。 |
レイアウト
| コンポーネント | 説明 |
|---|---|
Container | 幅を制限します(例:最大幅 600px)。 |
Section | コンテンツをグループ化します。互換性のため、テーブルベースです。 |
Row | 水平方向の行です。 |
Column | Row 内の列です。幅は style で設定します。 |
コンテンツ
| コンポーネント | 説明 |
|---|---|
Heading | 見出しテキストです(as:h1~h6)。 |
Text | 本文テキストです。 |
Link | ハイパーリンクです(text、href)。 |
Button | ボタンのようなスタイルの CTA リンクです(text、href)。 |
Image | URL の画像です(src、alt、width、height)。 |
Hr | 水平線です。 |
ユーティリティ
| コンポーネント | 説明 |
|---|---|
Preview | 受信トレイのプレビューテキストです(Html 内)。 |
Markdown | Markdown コンテンツをメール対応の HTML に変換します。 |
メールのベストプラクティス
- 幅を制限します(例:Container の最大幅を 600px にします)。
- インラインスタイルまたは React Email の style props を使用してください。多くのクライアントでは
<style>ブロックが削除されます。 - 幅広いクライアントに対応するため、テーブルベースのレイアウト(Section、Row、Column)を優先してください。
- 画像には絶対 URL を使用してください。多くのクライアントでは、一部の状況で相対参照や cid: 参照がブロックされます。
- 複数のクライアント(Gmail、Outlook、Apple Mail)でテストしてください。可能であれば、プレビューツールまたは Litmus のようなサービスを使用してください。