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.htmlfile. 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.htmlfile, ending in/404.html. This means that you can define custom 404 paths for situations like/blog/404.htmland /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