Lovableで『問い合わせフォーム+自動返信メール』を作る完全ガイド|Resend連携
「Lovable 問い合わせフォーム」「Lovable メール送信」で検索した人向け。Googleフォームを卒業して、自社ドメインから自動返信メール+管理者通知が届くフォームを30分で作る手順を、非エンジニアにもわかる言葉で解説します。
0. この記事を読むとどうなる?#
あなたのLPやサービスサイトに、『お問い合わせ』ボタンを置きたい。でもGoogleフォームを貼り付けるとデザインが崩れて見栄えが悪いし、お客さんに自動返信を送る設定も面倒。送信通知もGmailのスレッドに埋もれて見落としがち——そんな状態を、この1記事で卒業します。
- サイトのデザインに溶け込む、自社製の問い合わせフォーム
- 送信したお客さんに『お問い合わせを受け付けました』の自動返信メール(自社ドメインから)
- 自分(運営者)には『新しい問い合わせが来ました』の通知メール
- 迷惑メール対策(簡易ハニーポット+送信レート制限)
- Slack通知や顧客リスト保存への発展先
1. ビフォー / アフター(現実例)#
- Before:Googleフォーム埋め込み/返信なし/通知はGmailの『フォーム送信』スレッドに埋もれる
- After:自社デザインのフォーム/お客さんに即自動返信/自分にも整形された通知メール/必要ならDBにも保存
2. 完成形のしくみ(図解)#
難しそうに聞こえますが、登場人物は3つだけです。
[サイト訪問者]
│ ① フォームに入力して送信
▼
[Lovableで作ったフォーム画面 (フロント)]
│ ② 入力内容をサーバー関数に渡す
▼
[Lovableのサーバー関数] ──────┐
│ │ ④ お客さんに自動返信
│ ③ Resend にメール送信依頼 ▼
└──────────────▶ [Resend] ──▶ [お客さんのメール受信箱]
└────▶ [運営者(あなた)のメール受信箱] ⑤ 通知メール- フロント:見た目(Lovableのチャットで作る)
- サーバー関数:『送信ボタン押された時にだけ動く小さな処理』。APIキーを安全に扱う場所
- Resend:メールを実際に配達してくれるサービス(無料枠あり)
3. 必要なもの(無料で揃います)#
- Lovableアカウント(Lovable Cloudを有効化しておく)
- Resendアカウント(無料枠:1日100通/月3,000通)
- 自分のドメイン(example.com など)。なくても検証だけならResendの共有ドメインで動きます
- 受信確認用のメールアドレス2つ(送信側・運営者側として動作確認するため)
4. Resendに登録してAPIキーを取る#
- https://resend.com にアクセスして『Sign up』
- 左メニュー『API Keys』→『Create API Key』
- Name: lovable-contact-form / Permission: Sending access のみ にする(最低権限が安全)
- 表示された re_xxxxx で始まる文字列をコピー(再表示できないので注意)
5. 自社ドメインから送れるようにする(任意・10分)#
この手順を飛ばすと、差出人は onboarding@resend.dev のような共有アドレスになります。テストはOKですが、本番ではほぼ確実に迷惑メール扱いされるので独自ドメイン認証を強く推奨します。
- Resend『Domains → Add Domain』→ 自分のドメインを入力(例:example.com)
- 表示される3〜4件のDNSレコード(SPF / DKIM / 任意でDMARC)をコピー
- ドメインを買ったサービス(お名前.com / Cloudflare / Route53など)の DNS設定 にそのまま貼り付け
- Resend側に戻り『Verify』をクリック。緑色の Verified になればOK(反映まで数分〜数時間)
6. LovableにResendのAPIキーをシークレット登録#
新規プロジェクトを作るか、既存プロジェクトを開いた状態で、チャット欄に次のように打ち込みます。
Resendを使って問い合わせフォームを作りたいです。
RESEND_API_KEY をシークレットに登録できるようにしてください。Lovableが下部にシークレット入力ダイアログを出してくれるので、コピーした re_xxxxx を貼り付けて保存します。これでフロントには絶対に露出しない場所に鍵が保管されます。
7. フォーム画面を作る(プロンプト例)#
Lovableチャットに、以下をそのままコピペして送るのが最短です。プロンプトは“何を出したいか”を素直に書くのがコツ。
/contact ページに、以下の問い合わせフォームを作ってください。
【入力項目】
- お名前 (必須)
- メールアドレス (必須・形式チェック)
- 会社名 (任意)
- 件名 (必須・最大100文字)
- お問い合わせ内容 (必須・最大2000文字・テキストエリア)
- ハニーポット用の hidden input 'website' (人間には見えない、空のままなら正常)
【動作】
- 送信ボタンを押すと、サーバー関数 sendContactEmail を呼ぶ
- 送信中はボタンを無効化して『送信中...』表示
- 成功したらフォームを消して『お問い合わせを受け付けました』のサンクスメッセージ
- 失敗したらエラーメッセージをフォーム上部に赤字で表示
【デザイン】
- サイトのブランドカラーに合わせる
- スマホでも見やすい縦並び8. メール送信のサーバー関数を作る#
次に、メールを実際に送る『裏側の処理』を作ります。チャットに次のように依頼してください。
src/lib/contact.functions.ts に sendContactEmail という createServerFn を作ってください。
【入力】name, email, company?, subject, message, website (honeypot)
【処理】
1. zodで入力をバリデーション
2. honeypot 'website' が空でなければ silently 200 を返す(ボット対策)
3. 同一IPからの連続送信は1分に3回までに制限(簡易メモリレート制限でOK)
4. Resend APIに2回送信:
(a) 運営者あて: from=noreply@example.com / to=ADMIN_EMAIL / 件名='[お問い合わせ] {subject}' / 本文に全項目
(b) 送信者あて: from=noreply@example.com / to={入力email} / 件名='お問い合わせを受け付けました' / 本文は受付確認 + 入力内容の控え + 返信目安(2営業日以内)
5. ADMIN_EMAIL は process.env から読む
【秘匿情報】
RESEND_API_KEY と ADMIN_EMAIL はシークレット経由。コードに直書き禁止。ADMIN_EMAIL も忘れずシークレット登録するよう依頼しましょう(運営者のメアドが公開リポジトリに出ない安全策)。生成されるコードはおおむね次の形になります。
// src/lib/contact.functions.ts
import { createServerFn } from "@tanstack/react-start";
import { z } from "zod";
const Input = z.object({
name: z.string().min(1).max(100),
email: z.string().email(),
company: z.string().max(100).optional(),
subject: z.string().min(1).max(100),
message: z.string().min(1).max(2000),
website: z.string().max(0).optional(), // honeypot: 空でなければボット
});
const recent = new Map<string, number[]>(); // IP→送信タイムスタンプ
export const sendContactEmail = createServerFn({ method: "POST" })
.inputValidator((d) => Input.parse(d))
.handler(async ({ data, request }) => {
if (data.website) return { ok: true }; // 静かに無視
const ip = request?.headers.get("x-forwarded-for") ?? "unknown";
const now = Date.now();
const hist = (recent.get(ip) ?? []).filter((t) => now - t < 60_000);
if (hist.length >= 3) throw new Error("送信が多すぎます。少し時間をおいてください。");
hist.push(now); recent.set(ip, hist);
const key = process.env.RESEND_API_KEY!;
const admin = process.env.ADMIN_EMAIL!;
const FROM = "お問い合わせ <noreply@example.com>";
const send = (payload: object) =>
fetch("https://api.resend.com/emails", {
method: "POST",
headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/json" },
body: JSON.stringify(payload),
});
// (a) 運営者通知
await send({
from: FROM, to: admin,
subject: `[お問い合わせ] ${data.subject}`,
reply_to: data.email,
html: `<h2>新しいお問い合わせ</h2>
<p><b>名前:</b> ${data.name}</p>
<p><b>メール:</b> ${data.email}</p>
<p><b>会社:</b> ${data.company ?? "-"}</p>
<p><b>件名:</b> ${data.subject}</p>
<p><b>本文:</b><br>${data.message.replace(/\n/g, "<br>")}</p>`,
});
// (b) 送信者への自動返信
await send({
from: FROM, to: data.email,
subject: "お問い合わせを受け付けました",
html: `<p>${data.name} 様</p>
<p>このたびはお問い合わせいただきありがとうございます。<br>
以下の内容で受け付けいたしました。2営業日以内にご返信いたします。</p>
<hr><p>件名: ${data.subject}</p>
<p>本文:<br>${data.message.replace(/\n/g, "<br>")}</p>`,
});
return { ok: true };
});9. テスト送信して動作確認#
- プレビュー画面の /contact を開く
- テスト用のメアド(自分のGmailなど)を入れて送信
- サンクスメッセージが出ることを確認
- 運営者のメアドに『[お問い合わせ] 〜』が届いていることを確認
- 送信側のメアドに『お問い合わせを受け付けました』が届いていることを確認
- Resendダッシュボード『Logs』で2通とも Delivered になっていればOK
10. よくあるつまずきポイント#
- メールが届かない/迷惑メール → from のドメインがResendで Verified になっているか再確認
- 『403 The from address does not match a verified domain』→ 5章のDNS設定が未反映。dig txt example.com で SPF/DKIM が見えるか確認
- 自分には届くがお客さんに届かない → 一部メールサーバーは noreply@ を強く弾く。info@ や hello@ にする手も
- ボットからの大量送信 → honeypotに加えてCloudflare Turnstileを追加するとさらに堅い
- 本文に絵文字や日本語が文字化け → Content-Type の charset ではなく、html フィールド内のHTML自体がUTF-8で送られているかを確認(Lovableが生成するfetchはデフォルトUTF-8でOK)
11. ここから広げられる『業務改善ネタ』#
- 問い合わせをLovable CloudのDBに保存して /admin/inquiries で一覧管理
- Slackコネクタで #sales チャンネルに即通知(取りこぼしゼロ)
- Google Sheetsコネクタで顧客リストに自動追記(営業に渡しやすい)
- Lovable AI Gatewayで『問い合わせ内容を3行に要約』してから通知メールに添える
- n8nに渡してCRM(HubSpot等)へリード自動登録
12. まとめ#
問い合わせフォームは『サイトの第一印象』であり、ここがダサいと商談前に信頼を失います。Lovable + Resend なら、デザインも返信メールも自社ブランドで揃えた状態を、半日もかからず立ち上げられます。まずは自分宛にテスト1通、を今日の目標にしてみてください。
実例ケーススタディ:問い合わせフォームの自動返信を15分で実装#
- Resendコネクタを有効化、送信ドメインを追加(SPF/DKIM/DMARCをDNSに設定)
- /contact フォームをLovableに依頼(Zod検証+ハニーポット)
- サーバー関数で『運営者宛通知メール』『送信者宛自動返信メール』の2通を送信
- テンプレートはReact Emailで共通レイアウト化(ロゴ・フッター・問い合わせ番号)
- 送信ログを contact_submissions テーブルに保存しadmin画面で検索
つまずきポイント集#
- 症状:Gmailで迷惑メール扱い → 対処:DKIMとDMARCを必ず通す。送信元は no-reply@独自ドメイン
- 症状:自動返信が無限ループ → 対処:From を no-reply@ にし、Reply-Toを問い合わせ窓口に。受信側が自動応答しないように Auto-Submitted: auto-replied ヘッダを付与
- 症状:日本語の件名が文字化け → 対処:UTF-8で必ずエンコード(Resend SDKは標準対応。手動編集しない)
- 症状:送信レートリミット → 対処:大量送信は分割+retry。マーケ用一斉送信は別経路(Brevo等)に分離
FAQ追加#
Q. ドメイン設定がうまくいかない
DNS反映に最大48時間かかります。digコマンドや MXToolbox でTXTレコードが見えてから検証ボタンを押してください。
Q. メルマガ送信に使える?
技術的には可能ですが、配信解除リンク・購読管理・配信統計が弱め。本格的なマーケメールはBrevoやMailchimpを併用するのが一般的です。
関連記事
※ 本記事は非公式の日本語ガイドです。最新情報は公式ドキュメントをご確認ください。