Netlify FormをGatsbyブログに導入する手順
6分目次
僕だけでしょうか?
【Netlify】Forms 機能を利用して問い合わせフォームを作成する
上の記事を参考にしたのですが、Netlify でフォームの追加ができませんでした。結論から言うと<form netlify>
のように form タグにnetlify
属性をつけるだけじゃ作動せず、公式ドキュメントを漁ったので、その共有です。
(2020/08 追記)今更ながら気付いたのですが Netlify Form でなく Google Form をiframe
で突っ込むのがベストプラクティスな気がしますね。実装が楽だし CSS でデザインも固められます
公式ドキュメント(英語)や GitHub を読める人向け
How to Integrate Netlify’s Form Handling in a React App
上記記事を読めば解決します。
Gatsby + Netlify Forms のデモサイトはこちらです。
このデモサイトのリポジトリはこちら。
メールアドレス欄をtest@test.com
にしたり、textarea
内が数文字だとスパムとみなされ、テスト投稿が弾かれてしまう可能性があります。参考: Form troubleshooting tips
公式ドキュメント苦手な人向け
Form コンポーネントの作成
/src/components に Form コンポーネントを作りましょう。
import React, { useState } from "react";
import { navigate } from "gatsby-link";
const encode = (data) => {
return Object.keys(data)
.map((key) => encodeURIComponent(key) + "=" + encodeURIComponent(data[key]))
.join("&");
};
const Form = () => {
const [state, setState] = useState({});
const handleChange = (e) => {
setState({ ...state, [e.target.name]: e.target.value });
};
const handleSubmit = (e) => {
e.preventDefault();
const form = e.target;
fetch("/", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: encode({
"form-name": form.getAttribute("name"),
...state,
}),
})
.then(() => navigate(form.getAttribute("action")))
.catch((error) => alert(error));
};
return (
<form
name="contact"
method="post"
action="/"
data-netlify="true"
data-netlify-honeypot="bot-field"
onSubmit={handleSubmit}
>
<input type="hidden" name="form-name" value="contact" />
<p hidden>
<label>
{" "}
<input name="bot-field" onChange={handleChange} />
</label>
</p>
<p>
<label>
Your name:
<br />
<input type="text" name="name" onChange={handleChange} />
</label>
</p>
<p>
<label>
Your email:
<br />
<input type="email" name="email" onChange={handleChange} />
</label>
</p>
<p>
<label>
Message:
<br />
<textarea name="message" onChange={handleChange} />
</label>
</p>
<p>
<button type="submit">Send</button>
</p>
</form>
);
};
export default Form;
あとは styled-components なり material-ui などで好きに見た目を整えてください。material-ui を使用する場合、こんな感じでしょうか。
import React, { useState } from "react";
import { navigate } from "gatsby-link";
import { makeStyles, TextField, MenuItem, Button } from "@material-ui/core";
const useStyles = makeStyles(() => ({
root: {
"& > *": {
marginBottom: "15px",
width: "100%",
},
},
}));
const encode = (data) => {
return Object.keys(data)
.map((key) => encodeURIComponent(key) + "=" + encodeURIComponent(data[key]))
.join("&");
};
const Form = () => {
const classes = useStyles();
const [state, setState] = useState({});
const handleChange = (e) => {
setState({ ...state, [e.target.name]: e.target.value });
};
const handleSubmit = (e) => {
e.preventDefault();
const form = e.target;
fetch("/", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: encode({
"form-name": form.getAttribute("name"),
...state,
}),
})
.then(() => navigate(form.getAttribute("action")))
.catch((error) => alert(error));
};
return (
<form
name="contact"
method="post"
action="/"
className={classes.root}
data-netlify="true"
data-netlify-honeypot="bot-field"
onSubmit={handleSubmit}
>
<input type="hidden" name="form-name" value="contact" />
<label hidden>
{" "}
<input name="bot-field" onChange={handleChange} />
</label>
<TextField
type="text"
label="お名前"
variant="outlined"
name="name"
onChange={handleChange}
/>
<TextField
type="email"
label="メールアドレス"
variant="outlined"
name="email"
onChange={handleChange}
/>
<TextField
name="message"
label="本文"
multiline
rows={4}
variant="outlined"
onChange={handleChange}
/>
<Button type="submit" variant="contained" size="large">
送信する
</Button>
</form>
);
};
export default Form;
普段 material-ui 使わなすぎてもし何か「ここはこうすべき」等ありましたらご指摘いただけると助かります……
使いたいところで呼び出し
使いたいページで呼び出しましょう。
import Form from "../components/Form";
const Hoge = () => {
return <Form />;
};
export default Hoge;
テストメールを送信し、Netlify から確認
うまく動作するかテストします。このときメールアドレス欄へのtest@test.com
の入力はやめましょう。スパム判定され、動作しない可能性があります(その場合、スパムフォルダに振り分けられます)。
フォームがうまく動作しているかはサイト詳細ページ(https://app.netlify.com/sites/サイト名/overview
)の form タグから確認可能です。
さきほど作った Form コンポーネントでは form タグの name 属性を
<form
name="contact" method="post"
action="/"
data-netlify="true"
data-netlify-honeypot="bot-field"
onSubmit={handleSubmit}
>
このようにcontact
にしています。この name 属性にあてた値が Netlify のフォーム確認ページで表示されます。
こちらのページでは問い合わせの確認、削除、CSV 形式でのダウンロードなどが可能です。
また、スパムメールもVerified submittions
のプルダウンからをSpam submittions
を選択すれば確認できます。
問い合わせがあったときに通知する
サイト詳細ページの Settings > Forms > Add notification から希望するアプリケーションへ通知することも可能です。Slack かメールを選択できます。また、その他のサービスに POST リクエストを投げることも可能です。
注意点
無料プランでは、100 件/月まで(ファイルのアップロードをできるフォームの場合は 10MB/月)の問い合わせのみになります。僕はブログを始めてもうすぐ丸 2 年近くになりますが、それでも月に 10〜20 件程度が最高なので今後もそれを上回らないといいのですが……。