はじめに
Next.jsの学習のためにお問い合わせフォームを作って見ようと思った。
SendGridやAmazon SESなどのAPIは使わず実装したかった。
TL;DL
nodemailerで作れた
nodemailerは、node.jsからメール送信を可能にするモジュール
実際にやったこと
入力画面作成(Bootstrap)
バリデーション追加(react-hook-form)
nodemailerを用いてメールを送信するAPIを作成
VercelではSMTPポートが使えなかったので、VPSにデプロイ
おわり
完成したお問合せフォーム
シンプルにメール送信だけを実装する手順
1. 新規アプリ作成&モジュールインストール
zsh.
npx create-next-app contact-form
npm i nodemailer
2. 入力画面作成
pages/index.js
import styles from "../styles/Home.module.css";
import { useState } from "react";
export default function Home() {
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [message, setMessage] = useState("");
const [submitted, setSubmitted] = useState(false);
const handleSubmit = (e) => {
e.preventDefault();
console.log("送信中");
let data = {
name,
email,
message,
};
fetch("/api/contact", {
method: "POST",
headers: {
Accept: "application/json, text/plain, */*",
"Content-Type": "application/json",
},
body: JSON.stringify(data),
}).then((res) => {
if (res.status === 200) {
console.log("送信が成功しました");
setSubmitted(true);
setName("");
setEmail("");
setMessage("");
}
});
};
return (
<div className={styles.container}>
<form className={styles.main}>
<formGroup className={styles.inputGroup}>
<label htmlFor="name">名前</label>
<input
type="text"
onChange={(e) => {
setName(e.target.value);
}}
name="name"
className={styles.inputField}
/>
</formGroup>
<formGroup className={styles.inputGroup}>
<label htmlFor="email">メールアドレス</label>
<input
type="email"
onChange={(e) => {
setEmail(e.target.value);
}}
name="email"
className={styles.inputField}
/>
</formGroup>
<formGroup className={styles.inputGroup}>
<label htmlFor="message">メッセージ</label>
<input
type="text"
onChange={(e) => {
setMessage(e.target.value);
}}
name="message"
className={styles.inputField}
/>
</formGroup>
<input
type="submit"
onClick={(e) => {
handleSubmit(e);
}}
/>
</form>
</div>
);
}
2. API作成
pages/api/contact.js
export default function sendmail(req, res) {
// 改行のエスケープシーケンスをbrタグに置換
const htmlMsg = req.body.message.replaceAll("\n", "<br>")
let nodemailer = require("nodemailer");
// 送信用アカウントの設定(ここではGmail)
const transporter = nodemailer.createTransport({
port: 465,
host: "smtp.gmail.com",
auth: {
user: "sender@gmail.com",
// Googleアカウントでアプリパスワードを取得して入れる
pass: 'google_application_password',
},
secure: true,
});
// 管理人に送るお問い合わせメッセージ通知メール
const toHostMailData = {
from: 'sender@mail.com',
to: "host@mail.com",
subject: `【お問い合わせ】${req.body.name}様より`,
text: req.body.message + " | Sent from: " + req.body.email,
html: `
<p>【名前】</p>
<p>${req.body.name}</p>
<p>【メッセージ】</p>
<p>${htmlMsg}</p>
<p>【メールアドレス】</p>
<p>${req.body.email}</p>
`,
};
// ゲストに送る自動受付メール
const toGuestMailData = {
from: 'sender@mail.com',
// 入力されたゲストのメールアドレスが入る
to: `${req.body.email}`,
subject: `【お問い合わせ自動受付メール】`,
text: req.body.message + " | Sent from: " + req.body.email,
html: `
<p>
お問い合わせありがとうございます。
<br>以下の内容でお問い合わせを承りました。
</p>
<p>-----------------------------------------</p>
<h2>お問い合わせ内容</h2>
<p>【名前】</p>
<p>${req.body.name}</p>
<p>【メッセージ】:</p>
<p>${htmlMsg}</p>
<p>【メールアドレス】</p>
<p>${req.body.email}</p>
<p>-----------------------------------------</p>
`,
};
// 送信する
transporter.sendMail(toHostMailData, function (err, info) {
if (err) console.log(err);
else console.log(info);
});
transporter.sendMail(toGuestMailData, function (err, info) {
if (err) console.log(err);
else console.log(info);
});
res.send('success');
}
動作確認
zsh.
npm run dev
参考文献
Coding a Contact Form with Next.js and Nodemailer
高度な使用法 | React Hook Form - Simple React forms validation
↧