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 コンポーネントを作りましょう。

/src/components/Form.js
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 を使用する場合、こんな感じでしょうか。

/src/components/Form.js
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 使わなすぎてもし何か「ここはこうすべき」等ありましたらご指摘いただけると助かります……

使いたいところで呼び出し

使いたいページで呼び出しましょう。

/src/pages/hoge.js
import Form from "../components/Form";

const Hoge = () => {
  return <Form />;
};

export default Hoge;

テストメールを送信し、Netlify から確認

うまく動作するかテストします。このときメールアドレス欄へのtest@test.comの入力はやめましょう。スパム判定され、動作しない可能性があります(その場合、スパムフォルダに振り分けられます)。

フォームがうまく動作しているかはサイト詳細ページ(https://app.netlify.com/sites/サイト名/overview)の form タグから確認可能です。

Netlifyフォームがうまく動作しているかの確認

さきほど作った Form コンポーネントでは form タグの name 属性を

/src/components/Form.js
    <form
      name="contact"      method="post"
      action="/"
      data-netlify="true"
      data-netlify-honeypot="bot-field"
      onSubmit={handleSubmit}
    >

このようにcontactにしています。この name 属性にあてた値が Netlify のフォーム確認ページで表示されます。

Netlifyフォームがうまく動作しているかの確認

こちらのページでは問い合わせの確認、削除、CSV 形式でのダウンロードなどが可能です。

Netlifyフォームがうまく動作しているかの確認

また、スパムメールもVerified submittionsのプルダウンからをSpam submittionsを選択すれば確認できます。

Netlifyフォームがうまく動作しているかの確認

問い合わせがあったときに通知する

サイト詳細ページの Settings > Forms > Add notification から希望するアプリケーションへ通知することも可能です。Slack かメールを選択できます。また、その他のサービスに POST リクエストを投げることも可能です。

Netlifyフォームでの問い合わせを通知する

注意点

無料プランでは、100 件/月まで(ファイルのアップロードをできるフォームの場合は 10MB/月)の問い合わせのみになります。僕はブログを始めてもうすぐ丸 2 年近くになりますが、それでも月に 10〜20 件程度が最高なので今後もそれを上回らないといいのですが……。

  • SNSでシェアしよう
  • Twitterでシェア
  • FaceBookでシェア
  • Lineでシェア
  • 記事タイトルとURLをコピー
トップへ戻るボタン

\ HOME /

トップへ戻る