NuxtJSで Formrunで作ったフォームがうまく動かない時の対処方


注意

この記事を書いている時の
formrunのsdkはバージョン v2.2.0 です。
サービスのアップデートによって仕様が変わる可能性があるので、
ご注意ください。

問題

formrun (フォームラン)
https://form.run/ja

で、今流行りの「Jamstack」のフォームを作ろうと思い、
NuxtJSでゴリゴリ実装していると、とある問題に直面しました。

◎ contactページに直接飛んだ場合

→ 例えば、空欄にして、submitを押すと、ちゃんとバリデートが動きます。

× TOPページ ⇨ contactページと「nuxt-link」タグで遷移した場合

→ フォームが空のままでもそのままsubmit出来てしまう。

原因

NuxtJSでは、静的にhtmlを生成させているはずなのに、、preloadが原因なのか。
通常のページ遷移と違って、formrunのsdkを読み込んだ時に、フォームのhtmlが無いからとか?
この辺が曖昧だが、多分読み込みの順序の問題だと思う。
SPAとか非同期遷移のサイトでも同じ問題が起きる気がする。(知らないけど)

問い合わせる

formrunカスタマーサポートに問い合わせる。
夜に送ったら翌日すぐ返信くれました。

自分

他のページから非同期でアクセスした際は、バリデートがうまく動作しません。(nuxt.jsで構築しております)。そのようなページの場合、どうすれば正常に動作するでしょうか?ページ遷移の際に専用のメソッドを叩く、等ありましたらご教授いただけますでしょうか?

良く考えたら非同期じゃないけど、これの方が伝わりやすいから結果オーライ

運営からのご回答

こちらにつきましては、
動的に生成されたフォームに
バリデーションを利用する方法といたしまして、
下記の方法にて、動作を確認していただけますと幸いです。

(1). ページロード完了するまでに待ち
(2). `window.Formrun._reset()` を実行し、formrun.jsのリセットを行う。
(3). `window.Formrun.init('.formrun')` を実行し、formrun.jsの再適応を行う。

なるほど〜

解決コード

これで直った。

pages/contact.vue

export default {
  mounted() {
    if (process.client) {
      this.loadFormrunScript()
    }
  },
  methods: {
    initFormrun() {
      window.Formrun._reset() // (2)の処理
      window.Formrun.init('.formrun') // (3)の処理
    },
    loadFormrunScript() {
      if (window.Formrun) { // 一度アクセスしたら、window.Formrunがあるので、(2),(3)の処理を呼んで終わり
        console.log('repeat init')
        this.initFormrun() 
        return  // 2回目からはここで終わり
      }
   // 初回のみ SDKを ロードする
      new Promise((resolve, reject) => {
        // (1). 該当スクリプトを動的にロード
        const script = document.createElement('script')
        script.addEventListener('load', resolve)
        script.addEventListener('error', reject)
        script.src = 'https://sdk.form.run/js/v2/formrun.js'
        document.head.appendChild(script)
      }).then(() => {
        console.log('init!') 
        this.initFormrun() // (2),(3)の処理を呼ぶ
      })
      .catch(() => {
        console.log('err')
      })
    },
  },

最後に

多分、ReactでSPAを構築する時などにも同じ問題が起きそうな気がしますので、試す価値ありかと。
Jamstackが流行ってくると、PHPでフォームを作るのではなく、「formrun」のような、クライアントサイドのみで完結するフォームのサービスが流行ってくる気がします。