はじめに
Gatsby + Netlify + React Hook Formでお問い合わせページを作成する方法を解説します。 結果としては1回のデプロイでフォームの機能は動くようになりましたが、悩みましたのでメモしておきます。
結論
以下のようなコードで動きました。
フォームの内容を送信したあとは画面遷移させたり、トーストを表示したりはお任せします。
src/pages/contact.jsなど
import React from "react";
import { useForm } from "react-hook-form";
// データのエンコード処理
function encode(data) {
return Object.keys(data)
.map((key) => encodeURIComponent(key) + "=" + encodeURIComponent(data[key]))
.join("&");
}
export const Contact = () => {
const {
register,
handleSubmit,
formState: { errors }
} = useForm();
const onSubmit = (data) => {
// データの送信処理、form-nameをformのnameと合わせる。
fetch("/", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: encode({ "form-name": "contact", ...data })
})
.then(() => {
// 成功時の処理
})
.catch((error) => {
// 失敗時の処理
});
};
return (
// name属性とdata-netlify="true"が必要ここのデータをもとにFormが登録される。
<form
noValidate
name="contact"
data-netlify="true"
onSubmit={handleSubmit(onSubmit)}
>
// formの内容は任意
<p>
名前: <input type="text" {...register("name", { required: true })} />
</p>
{errors.name && errors.name.type === "required" && (
<p style={{ color: "red" }}>必須です。</p>
)}
<p>
メールアドレス:{" "}
<input type="email" {...register("email", { required: true })} />
{errors.email && errors.email.type === "required" && (
<p style={{ color: "red" }}>必須です。</p>
)}
</p>
<p>
件名:
<input type="text" {...register("title", { required: true })} />
{errors.title && errors.title.type === "required" && (
<p style={{ color: "red" }}>必須です。</p>
)}
</p>
<p>
お問い合わせ内容:{" "}
<textarea type="text" {...register("message", { required: true })} />
{errors.message && errors.message.type === "required" && (
<p style={{ color: "red" }}>必須です。</p>
)}
</p>
<button type="submit">送信する</button>
</form>
);
};
export default Contact;
悩んだところ
formのname属性
Netlifyはフォームの登録をformの「data-netlify」,「name」属性をみて作成するためこちらは必要になります。
こちらの属性がformに付与されているとNetlifyのビルドボットがフォームを登録してくれます。 その際に作成されるフォームの名前がformの「name」属性となります。
name属性の値は任意ですので、わかりやすい名前をつけるといいと思います。今回はお問い合わせということで「contact」と設定しています。
このname属性が無いと「form 1」のように登録されフォームのデータを送信しても正しく登録されなくなってしまいます。
form-name
ここが勘違いしてしまったのですが、form-nameという隠し要素は必要なのかということです。
こちらはどのフォームに送信するかを指定するものになっており、送信されるデータとしては必要なものになります。
逆を言えば最終的に送信されていればよいので今回はReact Hook Formを使用してデータを送信しましたのでinput要素としては必要ではなく、送信の際に付与すれば問題ありませんでした。
注意点としてはこちらはこの値はformのname属性の値と合わせる必要があります。
フォームの登録
フォームの登録は自動で行われます。Netlifyでのビルド時にformが存在すれば自動で登録されます。 以上の内容を参考にNetlifyでデプロイを行い以下のように登録されていれば完了となります。
おわりに
Netlifyは便利だなと思いました。他にも機能がありますので見てみて、つまづきポイントなどありましたら投稿したいと思います。