Next.jsのエラー画面が簡単&柔軟
Webアプリケーションの開発にかかせないエラー画面ですが、Next.jsでは簡単かつ柔軟に対応することができます。今回はそんなNext.jsのエラー画面表示の解説をします。また、ムーザルちゃんねるのYouTubeに解説した動画の公開もしています。動画ではより詳細に、記事では内容をすぐ把握できるよう簡易にしています。
Next.jsのエラーハンドリング挙動
Next.jsでは予期せぬエラー(例外)が発生したら自動でキャッチしてくれます。具体的に言うと、 error.tsx
というエラーコンポーネントを配置すると、自動でそのコンポーネントがレンダリングされます。
例外があると、error.tsxが表示される
ネストしたエラー表示
error.tsx
はどこの階層にも配置することができます。そして複数 error.tsx
がある場合、エラーが発生したページコンポーネントからディレクトリの上方向に見て、最も近い位置にある error.tsx
が採用されます。
一番近いerror.tsxが採用される
また、レンダリングされた error.tsx
よりも上の階層にあるレイアウトは再レンダリングされません。これを利用することでエラー表示を部分的にすることができます。以下の例を見てください。
トップレベルのerror.tsx | 同じ階層のerror.tsx |
---|---|
最初のものはエラーが発生したら画面全体にエラーメッセージが表示されます。もう一つは、部分的にエラーメッセージが表示されます。このようにレンダリングされた error.tsx
のディレクトリ位置と layout.tsx
の位置によって、レンダリング結果が異なります。
NotFoundの扱い
Next.jsではNotFoundもエラーと同様に not-found.tsx
ファイルが自動に表示されます。
この not-found.tsx
もネストすることができます。
指定ユーザが存在しないときの表示例。詳細のコンポーネント部分だけエラーにしている
おまけ:ユーザに不利益を与えないエラー対応
例えばユーザがフォームにテキストを入力してサブミットをしたとします。何かが原因で例外が発生しました。error.tsx
でキャッチされエラー表示が適切にされました。しかし、ユーザがさっきまで入力していたテキストは消えてしまいました…。
こんな経験、一度くらいはあるんじゃないでしょうか。すぐに再入力できる内容ならちょっとしたストレスで済みますが、長文を入力していたとしたら悲しくてユーザは離脱してしまうでしょう。そこで、ユーザに不利益を与えない形でエラーを表示する工夫が必要です。
ここでのアプローチは大きく2つあります。
-
error.tsx
にキャッチさせない - 入力内容をキャッシュさせる
error.tsx
にキャッチさせない
1. Next.js(AppRouter)では一般的にフォーム入力のサブミットにはServer Actionsを使います。Server Actions内部で例外が発生した時に、例外を無視するのではなく try..catch
で囲み、問題があれば error.tsx
ではなく自前でエラーハンドリングすることです。
export async function submit(formData: FormData) {
try {
// DBへの登録などの処理を行う
} catch(error) {
return { ok: false }
}
return { ok: true }
}
こうすればフォームの画面はそのままでServer Actionsの結果を受け取ってエラーメッセージを表示するようにすれば入力内容は失われません。もしくは例外を投げないようなライブラリの選定をするというのも一つの手です。
2. 入力内容をキャッシュさせる
これはGitHubなどでも採用されている手法です。ユーザが入力した内容を逐次ブラウザのSessionStorageに保存します。これを行うと、エラー時だけでなく、ページを再読込したり、他のページに遷移したあとでも入力内容を復元することができます。素晴らしいですね。
この仕組みはライブラリとして公開されているので誰でも使うことができます。
どちらの手法を使うか、あるいはそもそも考慮するかどうかは要件次第なのであなたのプロジェクトに合った方法を選択してください。
Discussion