この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
どうも、ベルリンオフィスの小西です。
静的サイト生成フレームワークであるGatsbyでは、しばらく前に Functions という動的なアプリが構築できる機能がリリースされています。ユーザー認証や外部APIへのリクエスト、サードパーティサービスとの連携などが可能になります。
先日、そのGatsby Functionsを使ってお問い合わせフォームを作ることがあったので、備忘録としてまとめておきます。
1. Gatsby立ち上げ
ローカルでGatsbyをインストールしてサンプルアプリを立ち上げます。
% npm install -g gatsby-cli
% gatsby new hello-world
% cd hello-world
% gatsby develop
http://localhost:8000/
にアクセスするとGatsbyのスターターサイトが立ち上がるはずです。今回はこれをベースに問い合わせフォームを実装してみます。
2. 必要なパッケージインストール
Gatsbyアプリからのメール送信用に Nodemailer を使います。
% npm install nodemailer
3. APIの作成
今回私はSMTPとしてSendgridを使いますが、Sendgridのセットアップは省略します。
まず、src
ディレクトリ直下に api
ディレクトリがない場合は作成します。
その中に form.js ファイルを作ります。ソースコードは下記です。
ご自身のSMTPに合わせて、 port
, host
, user
, pass
は適切な値にしてください。
src/api/form.js
export default function formHandler(req, res) {
let nodemailer = require('nodemailer')
const transporter = nodemailer.createTransport({
port: 465,
host: 'smtp.sendgrid.net',
auth: {
user: 'apikey',
pass: 'PASSWORD',
},
secure: true,
})
if (!req.body.email) {
return res.status(422).json("Email is required")
}
const mailData = {
from: 'TEST Sender <mail@example.com>',
to: req.body.email ? req.body.email : '',
subject: 'Thanks for the inquiry!',
html: req.body.emailBody ? `<p>${req.body.emailBody}</p>` : "Null message.",
}
const results = transporter.sendMail(mailData)
.then(result => res.status(200).json(JSON.stringify(result)))
.catch(error => res.status(500).json(JSON.stringify(error)))
}
やっていること
- ユーザーの入力した情報を元に自動返信メールを生成する(送信先=入力された `email` , 本文 = 入力された `emailBody` )
- `email` 欄の入力がなければエラーで返す
- SendgridのSMTPを使ってメールを送信を行い、成功したら200、エラーであれば500で返す
4. 問い合わせページの作成
次に、先ほどのAPIを呼び出すページを作成します。
ユーザーに、自分のEメールとメッセージのみを入力してもらうシンプルな入力フォームです。
src/pages/form.js
import * as React from "react"
import Layout from "../components/layout"
import Seo from "../components/seo"
export default function FormPage() {
const [value, setValue] = React.useState({})
const [serverResponse, setServerResponse] = React.useState('')
function handleChange(e) {
value[e.target.id] = e.target.value
setServerResponse('')
setValue({ ...value })
}
async function onSubmit(e) {
e.preventDefault()
const response = await window
.fetch('/api/form', {
method: 'POST',
headers: {
"content-type": "application/json",
},
body: JSON.stringify(value),
})
.then(res => res.json())
setServerResponse(response)
}
return (
<Layout>
<Seo title="Sample Contact Form" />
<h1>Sample Form Page</h1>
<div>
<h2>Server response</h2>
<p>{serverResponse}</p>
</div>
<hr />
<form onSubmit={onSubmit} method="POST" action="/api/form" className="formWrapper">
<h2>Contact Form</h2>
<div className="formBlock">
<label>
<span>Email</span>
<input
type="email"
name="email"
id="email"
value={value['email'] || ``}
onChange={handleChange} />
</label>
</div>
<div className="formBlock">
<label>
<span>Subject</span>
<textarea
name="emailBody"
id="emailBody"
value={value['emailBody'] || ''}
onChange={handleChange} />
</label>
</div>
<div className="formBlock">
<input type="submit" />
</div>
<div className="formBlock">
<input type="reset" value="Clear" />
</div>
</form>
</Layout>
)}
これで構築は完了しましたので、実際に触ってみます。
5. 実際に動かしてみる
http://localhost:8000/form/
をブラウザで開きます。
※「4. 問い合わせページの作成」で作ったページに別途CSSをあてています。
自分のメールアドレスと適当なメッセージを入力し、「Submit」を押します。
Server Responseが無事返ってくれば成功です。
さらに、入力したメールアドレス宛に自動返信メールも届いているはずです。
さいごに
簡単にではありますが、Gatsby Functionsを試してみました。
Netlifyなどは静的サイトに組み込めるフォーム機能をホストマシン側で提供していましたが、これでGatsby単体で動的な機能の実装もできるようになりました。
いよいよシンプルな構成のサイトはGatsbyだけでOKという感じになってきて個人的に嬉しい限りです。