この記事ではNuxt.js v2系での説明となります。
Nuxt.jsではCSR時のエラーとSSR時のエラーで出力される画面が異なります。
CSR時であればapp/layouts/error.vue
が利用され、カスタマイズすることが可能です。
しかしSSR時に、例えばfetchで呼び出したaxiosのレスポンスのステータスコードが500系だった場合app/layouts/error.vue
は利用されず、Nuxt.js独自のエラー画面が出力されます。
SSR時のエラーページを変更する場合 app/views/error.html
を変更することで独自のエラー画面を作成することができます。
※srcDir: 'app',
としている場合はapp/app/views/error.html
となります。(ややこしい)
しかし、この場合だと表現できるエラーページは1種類となります。
ステータスコード別にエラーページを分けたい場合はどうしたら良いでしょうか。
ステータスコード別にエラーページを分ける
nuxt.config.js
の定義でhooksを利用することでNuxtアプリケーションがエラーになった場合に処理を差し込むことができます。
これを利用して任意のエラーページを表示させることが可能です。
hooksのrender.errorMiddleware
がNuxtアプリケーションがエラーになった場合に実行されます。
https://ja.nuxtjs.org/docs/2.x/internals-glossary/internals-renderer#%E3%83%95%E3%83%83%E3%82%AF
下記のコード例ではhttp statusが503の場合はyour/path/errors/503.html
が表示されそれ以外はyour/path/errors/error.html
が表示されます。
ステータスコード別のページを増やす場合はcase
を適宜追加することで動的に出し分けることが可能です。
import fs from 'fs'
///
hooks: {
render: {
errorMiddleware(app) {
app.use((error, _req, res, next) => {
const status = error.response.status
if (status >= 500) {
res.statusCode = status
res.setHeader('Content-Type', 'text/html; charset=utf-8')
let html
switch (status) {
case 503:
html = fs.readFileSync(`your/path/errors/${status}.html`)
break
default:
html = fs.readFileSync('your/path/errors/error.html')
}
res.end(html)
return
}
next(error)
})
}
}
},
(この機能、デフォルトで入っててほしいなー)