
GatsbyにNetlify Formのスパム対策
Netlify Formを利用すれば、serverlessのGatsbyにも問い合わせフォームを簡単に作れるでしょう。しかし、無料プランは1カ月100通のメッセージしか受信できないので、スパム対策しっかりしたほうがいいでしょう。( ´艸`)
普通のhttp postであれば、Netlify Formページのマニュアルを参照すれば難しくない組み込めますが、今回はAjaxで実装してみましょう。
要望
ランディングページにNetlify Formで組み込んだ問い合わせフォームのスパム対策します。
スパム対策。
- 
Honeypot field 
- 
reCAPTCHA 2 
Honeypot field
Honeypot fieldは英語なんですが、ここへ。
Ajaxでフォームをコミットするため、formにnetlify-honeypotを追加する必要がありません。非表示にinputを組み込めば簡単にできます。
const [inputs, setInputs] = React.useState({});
const handleChange = React.useCallback(
  (event) => {
    setInputs({
      ...inputs,
      [event.target.name]: event.target.value,
    });
  },
  [inputs],
);
<form>
  <p hidden>
    <label htmlFor="bot-field">
      Don’t fill this out: <input name="bot-field" onChange={handleChange} />
    </label>
  </p>
  <label>Email:<input type="text" name="email" onChange={handleChange} /></label>
</form>
reCAPTCHA v2
reCAPTCHAのキーペアを取得
https://www.google.com/recaptcha/admin, reCAPTCHA v2のサイトキーとシークレットキーを取得。

サイトキーとシークレットキーをコピーします。

Netlifyに環境変数を追加
Settings → Build & deploy → Environmentに下記を追加します。
- SITE_RECAPTCHA_KEY: サイトキー
- SITE_RECAPTCHA_SECRET: シークレットキー

ソースコードの修正
- 
react-google-recaptchaのインストールyarn add react-google-recaptcha
- 
formに data-netlifyとdata-netlify-recaptchaを追加<form data-netlify="true" data-netlify-recaptcha="true" > ... </form>
- 
サイトキーを .env.developmentに書き込むと、developモードで起動したら、Gatsbyが自動的にprocess.envに読み込んでくれます。(製品版のビルドするとき、同じ内容を.env.productionに書き込まなければいけない)SITE_RECAPTCHA_KEY=6LdtK6YZAAAAAK3iDB-14qX7bJv2d1KuIz_GR7LT
- 
reCAPTCHAコンポーネントをformに追加 import ReCAPTCHA from 'react-google-recaptcha'; const [recaptchaValue, setRecaptchaValue] = React.useState(""); const handleChangeReCAPTCHA = React.useCallback((value) => { setRecaptchaValue(value); }, []); <form data-netlify="true" data-netlify-recaptcha="true" > ... <ReCAPTCHA sitekey={process.env.SITE_RECAPTCHA_KEY} onChange={handleChangeReCAPTCHA} /> </form>
- 
submitするとき、パラメータ名 g-recaptcha-responseとしてvalueをPOSTするfetch("/", { ..., body: { "g-recaptcha-response": encodeURIComponent(recaptchaValue), } })
- 
ソースコードを整理 import ReCAPTCHA from 'react-google-recaptcha'; function ContactForm() { const [inputs, setInputs] = React.useState({}); const [recaptchaValue, setRecaptchaValue] = React.useState(""); const handleChange = React.useCallback( (event) => { setInputs({ ...inputs, [event.target.name]: event.target.value, }); }, [inputs], ); const handleChangeReCAPTCHA = React.useCallback((value) => { setRecaptchaValue(value); }, []); const handleSubmit = React.useCallback( (event) => { const submitForm = event.currentTarget; event.preventDefault(); event.stopPropagation(); if (recaptchaValue != null && recaptchaValue !== "") { fetch("/", { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: encodeObj({ "form-name": "form1", "g-recaptcha-response": recaptchaValue, ...inputs, }), }) .catch(() => console.log('POST ERROR')); } }, [inputs, recaptchaValue], ); return ( <form data-netlify="true" data-netlify-recaptcha="true" onSubmit={handleSubmit} > {/* You still need to add the hidden input with the form name to your JSX form */} <input type="hidden" name="form-name" value="form1" /> <p hidden> <label htmlFor="bot-field"> Don’t fill this out: <input name="bot-field" onChange={handleChange} /> </label> </p> <p> <label>Email: <input type="text" name="email" /></label> </p> <p> <label>Message: <textarea name="message"></textarea></label> </p> <p> <button type="submit">Send</button> </p> </form> ); }
完了
AjaxでNetlify FormをPOSTした場合、意外にワナが多くて、ご参考までに。

Blog part of ThunderMiracle.com
コメントは表示領域に入ると読み込みます