Nuxt.jsのSPAモードのファイルをレンタルサーバーにデプロイした時にリンク切れが起きる場合の対処法

# はじめに

意気揚々と「[初心に戻ってNuxt.js＋Vuetify ルーティングを学び直す](https://qiita.com/idani/items/ac793fd77b0ee3b3d080)」を作成して、レンサバにデモサイトとして設置しようとして問題が起きました。

なんとリンク切れが起きるのです！！

問題は2つありました。

# リンク切れの問題　その１

ブラウザに「 https://hirotae.com/nuxt/routing/user 」を入力すると、自動的に末尾に「/(スラッシュ)」が追加されて「 https://hirotae.com/nuxt/routing/user/ 」ます。

この結果、Nuxt.jsで作成したボタンリンクは、相対リンクで作成していますので、図の③のように、[https://hirotae.com/nuxt/routing/user/**user/159**](https://hirotae.com/nuxt/routing/user/user/159) となってしまいます。
![2020-04-12_17h27_49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133291/897153e8-be7b-9bfb-d2c1-3d7be8f7e206.png)

# 末尾のスラッシュがつかないようにしてみる。

末尾のスラッシュがつかないようにできないか調べてみると、Apacheの設定で[DirectorySlash](https://httpd.apache.org/docs/2.4/ja/mod/mod_dir.html#directoryslash)というのがあるようです。

ただ、私が利用しているレンタルサーバでは、`.htaccess`に記載をしても効果が発揮されませんでしたTT

# 末尾に強制的にスラッシュがつくようにする

検索をしていくと、[Nuxt.jsでURL末尾にスラッシュ(trailing slash)を付ける方法](https://knote.dev/post/2020-03-19/nuxt-trailing-slash/)という方法が見つかりました。

Nuxt.jpの公式サイトでも、[trailingSlash](https://ja.nuxtjs.org/api/configuration-router/#trailingslash)の記述がありました。

それでは実際に、`trailingSlash: true`を設定します。
また、サブディレクトリで動作しますので、`base: '/nuxt/routing/'`も追記しています。

```javascript:nuxt.config.js
export default {
  mode: 'spa',
  router: {
    base: '/nuxt/routing/',
    trailingSlash: true
  },
//省略
```

これで、http://localhost:3000/nuxt/routing/user/ を開くと、以下のように表示されますが、

![2020-04-12_17h45_40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133291/2a643b2f-d79b-619d-11ed-2bdf8421719a.png)

末尾のスラッシュがない、http://localhost:3000/nuxt/routing/user を開くと**404 Not Found** になりました。
![2020-04-12_17h45_28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133291/e86f8c6e-0925-975b-b291-daadf758ba2d.png)


[Nuxt.jsでURL末尾にスラッシュ(trailing slash)を付ける方法](https://knote.dev/post/2020-03-19/nuxt-trailing-slash/)の記事で、`middleware`で、末尾にスラッシュがない場合は、スラッシュ付きにリダイレクトするように教えていただいています。**ありがとうございます。**

以下のように、末尾にスラッシュがない場合は、末尾がスラッシュ付きにリダイレクトされて、リンク切れが起きないですね。
![2020-04-12_18h03_55.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133291/ed491174-aaf5-a812-d6d1-cd904454c036.gif)

`yarn build`した成果物をレンサバにおいてみます。
リンク切れなく動作しました。

https://hirotae.com/nuxt/routing/user/

![2020-04-12_18h11_15.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133291/89d9fed2-c56e-54eb-57f1-f7c3eb036db7.gif)


# リンク切れ問題その２

次のリンク切れは、vue-routerの問題になります。

低階層ならよいのですが、深い階層を表示しようとすると**404 Not Found**になります。

例えば、https://hirotae.com/nuxt/routing/user/262/friend/356 を直接開こうとした場合は、以下のようになります。
![2020-04-12_18h18_48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133291/c566419a-5f03-66eb-2b62-ba5a44a4292f.png)
※トップがワードプレスなので、ワードプレスのエラー画面にリダイレクトされてしまいました。

`yarn build`で生成された成果物を確認すると、`/user/index.html`までで、その後の階層の実ファイルはありません。

![2020-04-12_18h22_37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133291/f71c66b7-8fed-4bf2-1aa5-f6794b3c4beb.png)

残りのURLのページは、**JSによってブラウザ上で動的に生成している**ので、直接URLを参照した場合は、**レンタルサーバ上ではファイルがない**ので404になってしまいます。

vue-routerの公式ドキュメントの[HTML5 History モード](https://router.vuejs.org/ja/guide/essentials/history-mode.html)に記載のサーバ設定例を行っていきます。

だいたいのレンタルサーバは、Apacheで動作していますので、[Apacheの.htaccess](https://router.vuejs.org/ja/guide/essentials/history-mode.html#apache)の設定例を参考にします。

今回は、`/nuxt/routing/`サブディレクトリにデプロイしますので、以下のように記載します。

```apache:.htaccess
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /nuxt/routing/
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /nuxt/routing/index.html [L]
</IfModule>
```

# GitHub Pagesにデプロイする

レンタルサーバではありませんが、GitHub Pagesにもデプロイしたいですね。
一応、公式サイトに[GitHub Pages へデプロイするには？](https://ja.nuxtjs.org/faq/github-pages/)があります。

ただ、公式ドキュメントでは、generateモードなので、buildの場合ですと、`nuxt.config.js`に`router.base`の他に、`build.publicPath`の設定が必要でした。

```javascript:nuxt.config.js

export default {
  mode: 'spa',
  router: {
    base: '/nuxt-router-test/', <=ここ
    trailingSlash: true,
    middleware: 'trailingSlashRedirect'
  },
// 省略
  build: {
    /*
     ** You can extend webpack config here
     */
    publicPath: '/static/', <= ここ
    extend(config, ctx) {}
  }
}
```

デフォルトでビルドした場合には、`dist/_nuxt`というフォルダが作成されます。この`_nuxt`にアクセスができないために、`build.publicPath`でフォルダ名を`static`に変更します。
![2020-04-12_20h26_42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133291/25b4af42-e83f-f957-1bde-bf886dbd7161.png)![2020-04-12_20h23_22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133291/3378813a-b16c-cef7-c842-e03524512a90.png)

これで表示できるようになりました！

https://idani.github.io/nuxt-router-test/user/

# 最後に

Nutx.jsを利用する場合は、基本となっているvue-routerのドキュメントも目を通す必要がありますね。

開発環境だけでなく、実際にデプロイした場合の不具合を楽しめました。

今回作成したサンプルは、https://github.com/idani/nuxt-router-test2 で公開をしています。


あと、Nuxt.jsは、generateモードがありますので、そちらは、以下の設定を参考にして準備したいですね。

* [Nuxt.js(v2)でgenerate納品する前にやっておきたい設定](https://qiita.com/amishiro/items/11bd642728f6b5838189)