netlify form が楽勝すぎる
netlify は静的ファイルのホスティングサービスだが、フォームを簡単に埋め込むことができる。
受託制作において、これまで簡単なフォームを埋め込むために PHP が動く環境で動かしていたので、
netlify を使えば、簡単に組み込む事ができて便利。
詳細はドキュメントを見ていただければと思うが、 <form>
タグに netlify
の属性を追加するだけで、あとは通常どおり netlify 上で build して deploy すれば、なんとフォームが使えるようになる。
<form name="contact" method="POST" netlify>
<p>
<label>Your Name: <input type="text" name="name" placeholder="新垣結衣"></label>
</p>
<p>
<label>Your Email: <input type="email" name="email" placeholder="yui@aragaki.love"></label>
</p>
<p>
<label>Message: <textarea name="message" placeholder="新垣結衣のホームページをつくりたいです。など"></textarea></label>
</p>
<p>
<button type="submit">Send</button>
</p>
</form>
しかも、csv でダウンロードできるし、Slack に飛ばすことができるし、楽勝で form が使えます。
やっぱり netlify 好きです。
nuxt generate だと、全然楽勝じゃない、、
ただ、上記 html を vue コンポネントの template 書いて、nuxt generate したファイルを netlify に上げてもうまくいかなかった。
具体的には、下記のエラーが developer tools の console に出た。
[nuxt] Error while initializing app DOMException: Failed to execute 'appendChild' on 'Node': This node type does not support this method.
at Object.appendChild
これは、生成された html と component を利用してレンダリングをする html が異なる場合に、エラーになるっぽい。(多分)
また、<nuxt-link>
での dom書き換えによる遷移後も、エラーがでないものの通常のPOSTのフォームの挙動となり、正常に動作しなかった。
原因
そこで、netlify にホスティングされた生成された html をみると、
<form name="contact" method="POST">
<input type="hidden" name="form-name" value="contact">
<p>
<label>Your Name: <input type="text" name="name" placeholder="新垣結衣"></label>
</p>
<p>
<label>Your Email: <input type="email" name="email" placeholder="yui@aragaki.love"></label>
</p>
<p>
<label>Message: <textarea name="message" placeholder="新垣結衣のホームページをつくりたいです。など"></textarea></label>
</p>
<p>
<button type="submit">Send</button>
</p>
</form>
<input type="hidden" name="form-name" value="contact">
が追加されていることがわかった。
build するときに、html をパースして、type="hidden"
の input を差し込んでくれているみたい。
そしてそのとき合わせて POST のAPIを作ってくれることで、静的ホスティングサービスなのに、フォームが実現できるようだった。
だが、nuxt で作られるコンポーネントの dom は、この置換がされていないので、通常のフォームの挙動になってしまうし、nuxt が予期せぬ html があるということでエラーが出てしまっているのが原因っぽい。
##解決策
まず console のエラーをなくす解決策として、 <no-ssr>
<client-only>
タグを使うことで、generate する HTMLを無くして、ズレをなくした。
※追記 2020/02/05 <no-ssr>
は、nuxt3 から deprecated みたいなので、<client-only>
のが良さそうです。
<client-only>
<form name="contact" method="POST">
<input type="hidden" name="form-name" value="contact">
<p>
<label>Your Name: <input type="text" name="name" placeholder="新垣結衣"></label>
</p>
<p>
<label>Your Email: <input type="email" name="email" placeholder="yui@aragaki.love"></label>
</p>
<p>
<label>Message: <textarea name="message" placeholder="新垣結衣のホームページをつくりたいです。など"></textarea></label>
</p>
<p>
<button type="submit">Send</button>
</p>
</form>
</client-only>
すると無事エラーはとれた。※ type="hidden"
の input は含めたままにする。
追記 2020/02/05現在 ダミーを作らなくても API を生成してくれるようになったみたいです。
@kkotaro0111 さん情報ありがとうございます。
が!これではパースされる html がないので、今度はフォームのPOST APIが作られずに、通常の タグが埋め込まれるだけになってしまう。
次に、static/form.html を用意し、form.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>おといあわせ</title>
<link rel="stylesheet" href="">
</head>
<body>
<form name="contactform" method="post" netlify >
<input name="name" type="text" class="input is-success" placeholder="新垣結衣">
<input type="email" name="email" class="input is-success" placeholder="yui@aragaki.love">
<textarea name="message" class="textarea" placeholder="新垣結衣のホームページをつくりたいです。など"></textarea>
</form>
</body>
</html>
とnuxt generate とか関係ないダミーの html を用意し、build 時に POST API を作らせるようにした。
ちなみに、このパースされたフォーム内にある input の name 属性しか、paramで投げても受け入れてくれないので、 .vue
と input の数や属性は、揃える必要があった。
また一応このあたりで、リダレクトをかけることでダミーにはアクセスできないようにもできる。
https://www.netlify.com/docs/redirects/
こうすることで、なんとか nuxt generate
で生成したファイルでも 頑張って netlify form 使うことに成功した。
が、頑張って使ってて、全然スマートじゃないので、なんかいい方法あれば教えてください。