Skip to content

Turbolinks導入にあたっての問題(2020 04 29)

H Hasegawa edited this page May 7, 2020 · 1 revision

Turbolinks導入にあたっての問題

このドキュメントは2020/04/29に@hasehiro25によって書かれました

概要

TurbolinksをFjord boot campに導入するにあたって、現在解決が難しい問題に直面し、2020/04/29導入を断念いたしました。

将来Turbolinksを導入する方への参考になれば幸いです。

未解決の問題

ブラウザバックに対応できず、確認ダイアログが出せない

概要

編集中のフォーム(日報、FAQなど)からページ遷移すると確認ダイアログが表示されます。(warning.jsで実装されてる)

ダイアログを表示するためにbeforeunloadでページ遷移や更新イベントを検知し、イベントが発火されればevent.returnValue()でダイアログが出せる仕組みになっています。 Turbolinksでは仕組み上ページ遷移する時beforeunloadが発火されません。

ページ遷移にダイアログ対応できたものの、history-backに対応できませんでした。

試したこと

turbolinks:before-visit

turbolinks:before-visitとはTurbolinksがページ遷移する前に発火されるイベントです。

before-visitでページ遷移の時にconfirmでメッセージボックスを出すことはできました。

ページの更新とページを閉じるに発火しないので`beforeunload'と併用すると両方対応できる。

以下参考コードです。

const warningForm = document.querySelector('.js-warning-form')

const onUnload = () => {
  const message = 'このページを離れると、入力したデータが削除されます。本当に移動しますか?'
  window.addEventListener('beforeunload', e => {
    if (!submitting && !commentForm) {
      const warningForm = document.querySelector('.js-warning-form')
      if (!warningForm) { return null }
      e.preventDefault()
      e.returnValue = message
    }
  })
  window.addEventListener('turbolinks:before-visit', e => {
    if (!submitting && !commentForm) {
      const warningForm = document.querySelector('.js-warning-form')
      if (!warningForm) { return null }
      if (!confirm(message)) {
        e.preventDefault()
      }
    }
  })
}
warningForm.addEventListener('change', onUnload, false)

how to trigger " window.onbeforeunload " event under turbolinks ? - turbolinks - github

ただし、before-visitではhistory-backには対応してないそうです。

Full List of Events - turbolinks/github

canceling-visits-before-they-start -turbolinks/github

なのでhistory-backの前後でページ遷移の判定と遷移しないようにできないか考えました。

調べた結果、history-backを行うとpopstateイベントが発火され、ページ移行を止める手段がないので、history-backに対応するのは現状難しそうです。

onbeforeunload on back button - prevent user from losing unsaved changes turbolinks/github

参考

WindowEventHandlers.onpopstate - mdn

Window: beforeunload イベント - mdn

フォームがあるページからのリダイレクトでTurbolinksを切る

Turbolinksの設定にそのページにあるリンクからの遷移はTurbolinksを切るという設定があります。

Disabling Turbolinks on Specific Links turbolinks/github

設定を有効するとページ遷移がbeforeunloadで発火することが可能になり、ページ遷移、更新、閉じるに対応できます。

ただし、こちらも上記と同じ理由でhistory-backに対応できませんでした。


以下は当時発生した問題と解決した方法のメモ書きです

当時発生したが解決した問題

Stripeでコンソールにエラーが出る

Stripeをheadから読み込んでページを遷移すると 'Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('https://js.stripe.com') does not match the recipient window's origin ('http://localhost:3000'). というエラーがコンソールに出ます。 このエラーをStripe公式に問い合わせたところ、特に動作には問題のないとうことでした。公式は問題を把握しているものの、どう対応するか未定だそうです。

またruby-jpに確認したところ、動作に影響はないものの、エラーが出てる以上は予期せぬ動作が考えられ、スマートではないものの解決手段は用意されているのでそれを使った方が良いのではと教えていただきました。

最終的に、issueとプルリクを参考にStripeFormがあるページの前後に更新をかけ、フォームのないページではStripeのscriptを読み込まないように実装しました。(未レビュー)

Turbolinks and stripe - turbolinks/github

Add meta tag for opting in to full page reloads - turbolinks/github

GoogleTagMangerのプレビュー画面が表示されない

Turbolinksを有効にすると、ページ遷移するとGTMのプレビュー画面が表示されません。(計測そのものはしてます)

GTMのiframeが最初のページのbodyに紐づくため、ページ遷移するとプレビューが消えてしまう仕様です。

こちらは根本的な解決はできなかったものの、GTMが必要なのはWELCOME側であり、Turbolinksを使いたいのはログイン後の画面なので、WELCOME側ではTurbolinksを切るという方法で対処しました。

具体的な方法としてWELCOME内のリンクを全部turbolinksを無効にするプロパティを追加しました。

Disabling Turbolinks on Specific Links turbolinks/github

なお、GA側はそのままでは動かないで、ページ遷移を検知するためにコードの修正が必要です。

以上が実装のメモです。

将来誰かが代わりに実装してくれるのを期待しております:pray:

Clone this wiki locally