Gatsbyは静的サイトだけじゃない。Gatsby Funcstionsで問い合わせフォームを作ってみた。
どうも、ベルリンオフィスの小西です。
静的サイト生成フレームワークである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
は適切な値にしてください。
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 <[email protected]>', 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メールとメッセージのみを入力してもらうシンプルな入力フォームです。
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という感じになってきて個人的に嬉しい限りです。