Cloudflare PagesにNuxt 2のSPAを上げるとリロード時に404になる
困ってること
router.push
等のページ内遷移であれば問題なく動くんですが、リロードすると404になります。
全部で起こるわけではなくて、/users/_id.vue
みたいなDynamic Pagesを使っているページで起こります。
調べてもあまり出てこなかったので自分なりの解決方法を書いておきます。
Nuxt BridgeやNuxt 3でどうなるのかは知らないです。
なぜ404になるか
SSGがそういう仕様だから。
If you want Nuxt to generate routes with dynamic params, you need to set the generate.routes property to an array of dynamic routes.
例えばRESTっぽいユーザー管理ページがあるとします。
pages
├── users
│ ├── _id
│ │ ├── edit.vue
│ │ └── index.vue
│ ├── create.vue
│ └── index.vue
├── index.vue
出力はこうなります。
./dist
├── users
│ ├── create
│ │ └── index.html
│ └── index.html
├── favicon.ico
├── index.html
nuxt generate
では、pagesディレクトリの構造に沿ってHTMLを生成します。
ただ、ダイナミックなルートだとどんな値が来るの予測できないので生成のしようがないです。
なので生成されません。
Cloudflare Pagesの仕様
HTMLファイルが無かった場合、そのディレクトリからさかのぼって404.html
を探して返してくれます。
Not Found behavior
You can define a custom page to be displayed when Pages cannot find a requested file by creating a
404.html
file. Pages will then attempt to find the closest 404 page. If one is not found in the same directory as the route you are currently requesting, it will continue to look up the directory tree for a matching404.html
file, ending in/404.html
. This means that you can define custom 404 paths for situations like/blog/404.html
and /404.html, and Pages will automatically render the correct one depending on the situation.
どう解決したか
Cloudflare Pagesの仕様をうまく使います。
Nuxt 2ではSSGのデフォルトフォールバックファイルが200.html
ですが、それを404.html
に変えてしまいます。
nuxt.config.js
に設定を足して404.html
を生成するようにしてくれれば終わりです。
export default {
// ...
generate: {
// For Cloudflare Pages
fallback: '404.html',
},
Discussion