eureka

Netlify Forms を Nuxt(SSR/SSG)で使う

0

Netlifyが提供しているフォーム機能はとても簡単で便利なんじゃ。

Netlifyが提供しているフォーム機能のNetlify Forms。
メールサーバも不要でフォームが簡単に作れるらしいですが、Nuxtとかで使うときはちょっと工夫が必要なので自分のために覚書きします。

※こちらはSSGのやり方です。SPAの場合にはうまくいきませんのでご注意ください。

なおNetlifyのアカウントは登録済の前提でいきます!

環境

Nuxt 2.14.0

普通のフォームをつくる

まずは普通にHTMLのフォームを用意します。

自分のプロジェクトのコードはかなり関数化しているので、本家からサンプルコードをもってきました。

<form name="contact" method="POST" netlify>
  <p>
    <label>Your Name: <input type="text" name="name" /></label>   
  </p>
  <p>
    <label>Your Email: <input type="email" name="email" /></label>
  </p>
  <p>
    <label>Your Role: <select name="role[]" multiple>
      <option value="leader">Leader</option>
      <option value="follower">Follower</option>
    </select></label>
  </p>
  <p>
    <label>Message: <textarea name="message"></textarea></label>
  </p>
  <p>
    <button type="submit">Send</button>
  </p>
</form>

普通のフォームのformタグにnetlifyもしくはdata-netlify="true"をつけてプロジェクトに埋め込みます。

普通のHTML/CSSのプロジェクトであればこの状態で本番環境にアップすればOKです。

Nuxtでも使えるようにする

上記で作成したフォームのformタグ直下に下記のような隠し要素を追加します。

<form name="contact" method="POST" netlify>
  <!-- ここに追加 -->
  <input type="hidden" name="form-name" :value="contact" />
  <p>
    <label>Your Name: <input type="text" name="name" /></label>   
  </p>
  <!-- 省略します -->
</form>

なぜ隠し要素がいるのか?

公式によると、formタグにnetlify属性を指定することによって、レンダリングされたHTMLには上記の隠し要素のHTMLが埋め込まれるみたいなのですが、Nuxtではこの動作がエラーになってうまくいかないようです。

生成された html と component を利用してレンダリングをする html が異なる場合に、エラーになるっぽい。(多分)

楽勝すぎるはずの netlify form を nuxt generate で頑張って使う

そのため、先に自分で必要な要素を入れてしまいます。

デプロイする

普通のformにnetlify属性を入れて、隠し要素を入れたら本番デプロイするだけ。

デプロイが完了したことを確認してNetlifyにログイン、Formsタブを開くとHTMLでformタグに登録したフォーム名が表示されています。(初回だとおめでとうかなんか表示されていたかもです。)
登録したメールアドレスにもNetlifyからお知らせがきているはずです!

試しに本番環境のフォームからテスト送信して確認してみましょう。

ハマログ

これだけ簡単なのに、ここにたどりつくまでにいっぱいググって試しました笑
次の実装で忘れてまたループしないように私がハマったところを書いていきます。

ダミーファイルを作る

NuxtでNetlify Formsを使用するためにstatic配下にフォーム要素のみのHTMLファイルを作成する、という記事をよく見かけました。

結論からいうとこれはSPAのときにやるものでした。SSRであれば作成する必要はないです。

これについてはこちらでも触れていました。

実はNuxt.jsのSPAの場合、Netlifyがフォームの存在を認識出来ないのです。
なので対応した静的ページを作成しNetlifyに認識させてあげます。

【Nuxt.js】Netlify Formsの設置方法【Slack通知やメール通知も出来る】

client-onlyコンポーネントを使用する

こちらのQiitaから参考に試してみました。

楽勝すぎるはずの netlify form を nuxt generate で頑張って使う

あんまりよくわかってないですが、つけなくてもいけたのでいらなそうです←
申し訳程度にNuxt本家からの説明文を書いておきますw

このコンポーネントは、クライアント側でのみコンポーネントを意図的にレンダリングするために使用されます。

API: client-only コンポーネント

隠し要素入れてもうまくいかなかった

隠し要素のvalue属性がformタグのnameと一致している必要がありました。

ググると隠し要素入れればOK!みたいな感じでよく書いてありますが、隠し要素のどれが重要でなにがどれとかまで解説しているところがなくて、自分のプロジェクトに当てはめたときに地味にハマったやつです。

<input type="hidden" name="form-name" value="contact" />

上記の要素だと、name属性の内容はNetlify側でフォーム名を認識するためのものなのでいじらない。(よく考えたら分かったのですが、私はここをフォーム名だと思っていじってましたw)
valueのとこにフォーム名を入れます。

ついでにスパム対策

フォームを使用するだけなら上記で終わりなのですがついでにスパム対策もやりました。

ハニーポットフィールドというのをNetlifyが提供しているのですが、これを有効にするだけでOKです。

公式ではハニーポットフィールドを下記のように解説しています。

“ハニーポット “フィールドは、人間のユーザーが見ることのできないフィールドを入力するようにボットユーザーをおびき寄せる隠しフォームフィールドです。ハニーポットフィールドを入力して送信されたフォームは、ボットだけがそのフィールドを見て入力するので、安全に拒否することができます。netlify-honeypot属性をformに追加して、隠しフィールドの名前を指定することで、隠れたハニーポットフィールドをNetlifyに警告することができます。そして、そのフィールドがフォームに存在していることを確認してください。

Honeypot field

具体的な実装は下記のようになります。

<form name="contact" method="POST" netlify-honeypot="bot-field" netlify>
  <!-- どこに追加してもOK. cssで非表示にしておきます -->
  <p class="hidden">
    <label>Don’t fill this out if you're human: <input name="bot-field" /></label>
  </p>
</form>

ポイントは下記の2点です。

  • formタグにnetlify-honeypot="bot-field"をつける
  • <input name="bot-field" />を仕込む

ちなみに私のNuxtプロジェクトではform内に下記のように入れました。

  <div v-show="false">
    <label for="bot">スパムでない場合は空欄</label>
    <input id="bot" type="text" name="bot-field" />
  </div>

v-ifにしてしまうとDOMから消えてしまうので、v-showにしないとだめですが、こちらのほうがスタイルをいじらなくていいので圧倒的に楽ですね。

本当にスパム対策できてるか試してみる

上記のコードを埋め込んで、本番環境にデプロイしてから試します。

どうやら、ボットにだけ見えるフィールドに入力があるとスパムと見なす仕様なので、display: none;にした先ほどの隠し要素を検証ツールで表示して、適当に入力して送信します。

フォーム上では送信完了となっていましたが、NetlifyにログインしてFormsタブから確認しても先程送信した内容はどこにもありませんでした。

これによりスパム対策はできてそうと判断しました!

reCAPTCHAもできるみたいだけどやらなかった

スパム対策でハニーポットフィールドの他にもreCAPTCHA(リキャプチャ)が実装できるみたいでしたが、そこまでは不要だと判断して実装しませんでした。
前にスクールでアプリ開発をしたときにリキャプチャが出てきて実装が意味不明だった記憶があったので(初心者すぎただけかも)Netlifyで簡単にできたらいいですね。

reCAPTCHAをやる場合には下記の公式に解説がありますのでこちらからどうぞ。
https://docs.netlify.com/forms/spam-filters/#recaptcha-2-challenge

最後に

いやぁNetlify Formsは本当に便利すぎる!

お問い合わせを普通に実装しようと思ったらサーバやPHPやRubyといったバックエンド側の処理も必要になったり、WordPressでやるにしてもPHPバージョン問題とかで一筋縄ではいかなかったりしました。

お問い合わせ機能のためだけにWordPressを使用しないといけなかったこともありましたが、テーマをいじれないとデザインがかなり不自由で、機能をとるかデザインをとるかの取捨選択でしたw(今はそんなことないですが)

なので『HTMLに仕込むだけ、しかも無料。』は本当に神すぎます。
もちろん複雑なメール処理をさせたかったら有料プランとかにしないといけないかもですが、ポートフォリオや小規模なサイトにお問い合わせ機能をつけるくらいであれば十分です。

みんなでNetlify Forms使いましょう!!

参考

フォームの実装で参考にしたサイトをまとめます。

0