JavaScript
vue.js
vue-router
nuxt.js

Nuxt.jsのvue-routerの自動生成で詰んだ話

まさあき(@masaaakikunsan)です。
Nuxt.js を触っていますか? 僕は、01の開発の場合大体 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 では自動でやってくれるので非常に楽になります。

実際に見てみます。

スクリーンショット 2018-05-01 19.43.39.png

このようなファイル構造でindex.vueに nuxt-link で各ページにいけるようにしましょう。

pages/index.vue
<template>
  <section class="container">
    <div>
      <nuxt-link to="news">News</nuxt-link>
      <nuxt-link to="user/1">User</nuxt-link>
    </div>
  </section>
</template>

実際の挙動は以下のようになります。

Screenshot from Gyazo

ルーティングの定義通りになっているのがわかります。

スネークケースのファイルを作るとPage Not Foundになる

ルーティングに基本的に/hoge_hogeにすることはないとは思いますが、クライアントからの要望でそうせざるを得ない場合があるでしょう。
pages配下にcompany_about.vueというファイルを作ってみます。
index.vueに以下を追加して見ましょう

pages/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になります

Screenshot from Gyazo

https://trusting-lichterman-09c131.netlify.com/company_about
上記をクリックするとPage Not Foundになるかと思います。

解決方法

generate で吐き出されたdistを見て見ます。

スクリーンショット 2018-05-01 20.07.59.png

company_aboutディレクトがないのがわかります。

次に.nuxtディレクトリのrouter.jsを見て見ましょう。

スクリーンショット 2018-05-01 20.08.53.png

pathが/company:aboutになってしまっています。

これらからわかるように、 Nuxt.js ではアンダースコアを含むと全て動的ルーティングとして判断してしまっています。
generateコマンドでは動的なルーティングは全て無視されるので、nuxt.confing.jsに/company_aboutのルーティングを追加してあげる必要があります。

nuxt.config.js
generate: {
  routes: [
    '/company_about'
  ]
}

上記の記述をしたのちにgenerateをしてdistを見て見ましょう。

スクリーンショット 2018-05-01 20.16.59.png

company_aboutディレクトリがあるのが確認できました。
これでURLの直叩きやローディングしてもPage Not Foundになりません。

まとめ

そもそも、routingにアンダースコアが含まれることはほぼないと思いますが、クライアントの要望によってはそうせざるを得ない場合があるのでその場合はgenerateにルーティングを追加してあげましょう。

当然 Nuxt.js のドキュメントにもこのようなケースの対処方法は記載していないので、この記事が役に立てばなと。