Railsでwebpackerを利用してVue.jsを取り入れた完全SPAなサイトを構築しようとして、ページのルーティングを設定するためにVueRouterを導入しました。
VueRouterでルーティングを設定すると、デフォルトで下のようなURLに「#」が追加された状態で識別されてしまいます。
「#」が途中に混じっているのはあまりいいとはいえないため、VueRouterに「mode: ‘history’」という設定を加えて消してあげます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import Vue from 'vue' import VueRouter from 'vue-router' import Page1 from './pages/page1.vue' import Page2 from './pages/page2.vue' Vue.use(VueRouter) export default new VueRouter({ mode: 'history', //← 追加 routes: [{ path: '/', component: Page1 }, { path: '/page2', component: Page2 } ] }); |
これで解決か・・・と思いきや、新たな問題が発生してしまいます。
ページ切り替え後のURLを直接アドレスバーに入力して読み込みをかけると、Routing Errorもしくは404エラーが発生してしまいます。
調べても対策方法がまちまちで結局どうすればいいか悩みましたが、自己解決(正しい直し方かは不明)したので、今回はこのエラーの原因と対策方法について紹介したいと思います。
前提条件
・Rails 6.0.2
・vue 2.6.11
Routing Errorになる原因
VueRouterにかかわらずRoutingErrorの主な原因はroutes.rbに存在しない(マッチしない)パスが渡ってきた場合に起きるものです。
そんなページはこのサイトにはありません。という意味のエラーです。
例えば、VueRouterに「/page1」「/page2」というルーティングを設定していて、
Railsのroutes.rbに「get ‘page1’, to: ‘root#index’」はあるけど「get ‘page2’ , to: ‘root#page2’」の記述が無かったとします。
この場合、「/page2」を直接読み込むと、サーバーが反応しRailsのルーティングを検索して、マッチしない為にRoutingErrorエラーが発生してしまいます。
ちなみに、Railsのroutes.rbに「get ‘page2’ , to: ‘root#page2’」を追加してしまうとpage2.html.erbファイルを探しに行くので、それがないと別のエラーが発生します。
page2.html.erbファイルを作ってしまうと、全くの別ページを読み込むことになってしまい、それはもはやSPAではありません。
解決方法
解決方法はいたって単純でした笑
RoutingErrorエラーを回避するために、Railsのroutes.rbで以下のように管理します。
1 2 3 |
# 全てpages/indexを見にいくように設定する get 'pages/page1', to: 'pages#index' get 'pages/page2', to: 'pages#index' |
pages/indexのViewを、pages/page1でも、pages/page2でも、pages/hogehogeでも等しくpages/indexを見に行くように設定してあげます。
これでRoutingErrorエラーを回避することが出来るようになります。
実際にページ切り替えと、URL直接表示を行ってみると以下のようになります。
レイアウト&各種設定の参考:Rails 5.2で Webpacker + Vue.jsを使ってSPAを実現
単純ですが、意外と思いつかないものですね(私だけ?)