👻

nuxt2のエラーページについて調べた(ついでにnuxt3の違いを少しだけ)

2022/08/22に公開

はじめに

nuxtではエラーが発生した時に表示するページを作れる。このエラーはパスが無いなどのエラー以外に、Javascriptの例外なども含まれる。エラーページの使い方や、2系と3系でどうかわるか簡単に調べたのでまとめておく。

Custom Error Pages with nuxt.jsの和訳

エラーページはJavascriptのエラーをちゃんとハンドリングしてないときに自動的に表示してくれるのかと思っていたが、実際は表示するための関数だったりオブジェクトだったりがあって、何かしらのお作法がある。以下はその辺が勉強になったDaniel ‘mavrick’ Langさんのポストの和訳。最初のほうはマニュアルがアレってお話だったので省略。

Step1:エラーの処理

nuxt のドキュメントで概説されているように、 nuxtに適切な形式のエラーを返すためにasyncData()内部でerrorを呼び出すことができます。

export default { 
  asyncData ({ params, error }) { 
    return axios.get(` https://my-api/posts/${params.id}` ) 
    .then((res) => { 
      return { title: res .data.title } 
    }) 
    .catch((e) => { 
      error ({ statusCode: 404, message: 'Post not found' }) 
    }) 
  } 
}

Step2:カスタムエラーページを作成する

ここはちょっと変かもしれません。nuxt docsでは、カスタムレイアウトビューを作成する必要があると説明していますが、これはレイアウトではありません。配置場所がlayoutというだけです。

このテンプレートファイル内に<nuxt/>を含めないでください。通常のページビューとまったく同じように扱ってください。エラーオブジェクトはpropsに渡されます。

<template>
  <div class="container">
    <h1 v-if="error.statusCode === 404">Page not found</h1>
    <h1 v-else>An error occurred</h1>
    <nuxt-link to="/">Home page</nuxt-link>
  </div>
</template>
<script>
export default {
  props: ['error'],
  layout: 'blog' // you can set a custom layout for the error page
}
</script>

step1でerrorをerror({ statusCode: 400, message: 'Post not found' })のように呼び出したことを思い出してください。ここで設定したstatusCodemessageが上記サンプルのエラーオブジェクトに設定されており、使えるようになっています。

<h1 v-if="error.statusCode === 404">Page not found</h1>

以上です。nuxt アプリに存在しないルートに移動してこれをテストすると、新しいカスタム エラー ページが表示されるはずです。

ボーナスラウンド

あなたが私のような人なら、さまざまなエラー状態を管理するためにいくつかの追加コンポーネントをセットアップしたいと思うでしょう。これにより、コードもきれいに保たれます。

./layouts/error.vue

<template>
  <div class="nuxt-error">
    <component :is="errorPage" :error="error" />
  </div>
</template>
<script>
import error404 from '~/components/error/404.vue';
import error500 from '~/components/error/500.vue';
export default {
  name: 'nuxt-error',
  layout: 'default', // optional
  props: {
    error: {
      type: Object,
      default: () => {},
    },
  },
  computed: {
    errorPage() {
      if (this.error.statusCode === 404) {
        return error404;
      }
      // catch everything else
      return error500;
    },
};
</script>

./components/error/404.vue

<template>
  <div class="error-404">
    <h1>This page doesn’t exist</h1>
    <p>The link you clicked on may be broken or no longer exist.</p>
  </div>
</template>
<script>
export default {
  name: 'error-404',
  props: {
    error: {
      type: Object,
      default: () => {},
    },
  },
};
</script>

↑について追記

  • asyncDataじゃないところでerror()が使いたい場合はthis.$nuxt.error()で呼び出せる
  • typescriptで使うとき、error()の引数は以下の通り
export interface NuxtError {
  message?: string
  path?: string
  statusCode?: number
}

2と3の違い

  • コンポーネントの配置場所
    • nuxt2はlayouts/error.vue
    • nuxt3は~/error.vue
  • 3にはエラーヘルパーメソッドがある。以下は自分の理解。詳細は公式参照
    • useError():エラー内容を取得できる。propsの代わりに使える。
    • createError(): パラメータを追加したerrorオブジェクトを作れる。オブジェクトはそのままスローされることを意図している。
    • showError():呼び出してすぐエラーページを表示する。error.vueとは違う模様。createError()のほうを使ってほしいとのこと。
    • clearError():エラーのクリア。エラーページから移動するときに呼び出す。エラーページから普通のページに移動するときに必ず呼ばないといけない?

おわりに

nuxtのエラーページの使い方について調べた。

参考文献

nuxt2の公式
nuxt3の公式
Custom Error Pages with nuxt.js

Discussion