まさあき(@masaaakikunsan)です。
Nuxt.js を触っていますか? 僕は、0→1の開発の場合大体 Nuxt.js でやらせてもらっています。
今回は Nuxt.js の便利な機能の一つの vue-router の自動生成で詰んだ話を書きます。
TL;DR
- pages配下にスネークケースのファイルを作るとPage Not Foundになる
- generate の動的なルーティングの配列をセットすると治る
Nuxt.js の Vue Router のルーティング定義自動生成
Nuxt.js では pages ディレクト内の .vue ファイルの構造に沿って、自動的に Vue Router の設定を生成してくれます。
例えば、下記のようなファイルの構造のときは
page/
--| index.vue
--| news.vue
--| user/
----| _id.vue
以下のような定義が自動的に生成されます。
router: {
routes: [
{
name: 'index',
path: '/',
component: 'pages/index.vue'
}, {
name: 'news',
path: '/news',
component: 'pages/news.vue'
}, {
name: 'users-id',
path: '/users/:id?',
component: 'pages/users/_id.vue'
}
]
}
このように、.vue ファイル名またはディレクトリ名にアンダースコアのプレフィックスを付けるとパラメータを使って動的なルーティングを定義できます。
Vue.js ではルーティングを自分で定義する必要がありますが、 Nuxt.js では自動でやってくれるので非常に楽になります。
実際に見てみます。
このようなファイル構造で index.vue に nuxt-link で各ページに遷移できるようにしましょう。
<template>
<section class="container">
<div>
<nuxt-link to="news">News</nuxt-link>
<nuxt-link to="user/1">User</nuxt-link>
</div>
</section>
</template>
実際の挙動は以下のようになります。
ルーティングの定義通りになっているのがわかります。
スネークケースのファイルを作るとPage Not Foundになる
上記の通り、非常に強力で便利な機能ですが、ルーティングにアンダースコアをつけると問題が生じます。
通常、 /hoge_hoge などの形式にすることはあまりないとは思いますが、クライアントからの要望でそうせざるを得ない場合を想定しましょう。
pages 配下に company_about.vue というファイルを作成後、 index.vue に以下を追加してみましょう。
<template>
<section class="container">
<div>
<nuxt-link to="news">News</nuxt-link>
<nuxt-link to="user/1">User</nuxt-link>
<nuxt-link to="company_about">Company About</nuxt-link>
</div>
</section>
</template>
実際の挙動を見て見ましょう。
company_about ページには nuxt-link で遷移して正しく表示されますが、リロードやURLを直で入力するとPage Not Foundになります
https://trusting-lichterman-09c131.netlify.com/company_about
上記をクリックすると Page Not Found になるかと思います。
解決方法
問題を正しく認知するため、まずは generate で吐き出された dist を見て見ます。
company_about ディレクトがないのがわかります。
次に .nuxt ディレクトリの router.js を見て見ましょう。
path が /company:about になってしまっています。
これらからわかるように、 Nuxt.js ではアンダースコアを含むと全て動的ルーティングとして判断してしまっています。
generate コマンドでは動的なルーティングは全て無視されるので、 nuxt.confing.js に /company_about のルーティングを追加してあげる必要があります。
generate: {
routes: [
'/company_about'
]
}
上記の記述をしたのちに generate をして dist を見て見ましょう。
company_about ディレクトリがあるのが確認できました。
これで URL の直叩きやローディングしても Page Not Found になりません。
まとめ
そもそも、 routing にアンダースコアが含まれることはほぼないと思いますが、クライアントの要望によってはそうせざるを得ない場合があるのでその場合は generate にルーティングを追加してあげましょう。
当然 Nuxt.js のドキュメントにもこのようなケースの対処方法は記載していないので、この記事が役に立てばなと。