1. yahsan2

    Posted

    yahsan2
Changes in title
+楽勝すぎるはずの netlify form を nuxt generate で頑張って使う
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,134 @@
+## netlify form が楽勝すぎる
+netlify は静的ファイルのホスティングサービスだが、フォームを簡単に埋め込むことができる。
+
+受託制作において、これまで簡単なフォームを埋め込むために PHP が動く環境で動かしていたので、
+netlify を使えば、簡単に組み込む事ができて便利。
+
+https://www.netlify.com/docs/form-handling/
+
+詳細はドキュメントを見ていただければと思うが、 `<form>` タグに `netlify` の属性を追加するだけで、あとは通常どおり netlify 上で build して deploy すれば、なんとフォームが使えるようになる。
+
+
+```html:vue
+<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 をみると、
+
+```html:vue
+<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>` タグを使うことで、generate する HTMLを無くして、ズレをなくした。
+
+```html:vue
+<no-ssr>
+<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>
+</no-srr>
+```
+
+すると無事エラーはとれた。※ `type="hidden"`の input は含めたままにする。
+
+が!これではパースされる html がないので、今度はフォームのPOST APIが作られずに、通常の<form> タグが埋め込まれるだけになってしまう。
+
+次に、static/form.html を用紙し、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 使うことに成功した。
+
+が、**頑張って**使ってて、全然スマートじゃないので、なんかいい方法あれば教えてください。
+
+