🚫

notFound() が error.tsx に喰われるのをなんとかする

2023/07/22に公開

はじめに

以下の構成のような not-found.tsx を置いた箇所よりもネストの深いディレクトリに error.tsx を置いた状態で、そのルートを通るページで notFound() を使用すると、not-found.tsx ではなく error.tsx が表示されてしまう。

src/app
├── path
│   ├── error.tsx
│   └── [id]
│       └── page.tsx  <-- ここで notFound() 呼び出し
├── not-found.tsx
└── page.tsx

確認用のリポジトリとサイトは以下
https://github.com/sekiya9311/sample-next-not-found-error
https://sample-next-not-found-error-sekiya9311.vercel.app/

確認時の Next.js のバージョンは 13.4.12

原因

notFound() 自体が、NEXT_NOT_FOUND というメッセージを持たせた Error を throw するだけのため[1]error.tsx を置いたときに Next.js によって設置される Error Boundary がこれに反応してしまう。
https://github.com/vercel/next.js/blob/bc9d69dea45d6ae6545165b9c2651082927124bb/packages/next/src/client/components/not-found.ts

対処

error.tsx で、エラーが NEXT_NOT_FOUND だったら rethrow する。
https://github.com/sekiya9311/sample-next-not-found-error/blob/main/src/app/ok/error.tsx
お誂え向きな isNotFoundError なる関数が存在しているので、これで判定が可能。
この関数の内部処理は、digest プロパティ見てるだけなので、直接そっちを確認する形でもOK。
https://github.com/vercel/next.js/blob/bc9d69dea45d6ae6545165b9c2651082927124bb/packages/next/src/client/components/not-found.ts#L16-L25

余談

これってバグ?仕様?(仕組み上、仕方がなかったりする?)

脚注
  1. https://nextjs.org/docs/app/api-reference/functions/not-found#notfound ↩︎

Discussion