TL;DR

App Router の app ディレクトリに置く特別なファイルの 1 つ。リソースが見つからなかったことを伝えるページ(404 ページ)を定義する。

export default function NotFound() {
  return <div>Not Found</div>
}

仕組み

置いた URL Segment 配下のすべての URL Segment で、notFound 関数が呼ばれたときに表示される。notFound は例外を投げ、Next.js が内部でその例外を catch する設計になっている。

export function notFound(): never {
  // eslint-disable-next-line no-throw-literal
  const error = new Error(NOT_FOUND_ERROR_CODE)
  ;(error as NotFoundError).digest = NOT_FOUND_ERROR_CODE
  throw error
}

例

page.tsx や layout.tsx で Web API からデータを取得し、リソースが見つからなかったときは、慣習として notFound を呼ぶ。

import { getPage } from "@/utils"
import { notFound } from "next/navigation"
import styles from "./page.module.css"
 
type Props = {
  params: { categoryName: string }
  searchParams: { [key: string]: string | string[] | undefined }
}
 
export default function Page({ params, searchParams }: Props) {
  const page = getPage(searchParams)
  if (page > 10) {
    notFound()
  }
 
  return (
    <div>
      <h1>カテゴリー別一覧画面</h1>
      {/* ... */}
    </div>
  )
}

注意点

公式ドキュメントによると、ストリーミングが始まる前なら Next.js は ステータスコード 404 を返すが、始まった後はステータスコードが 200 のまま not-found の UI を描画する。どちらの場合も <meta name="robots" content="noindex" /> が挿入される。

ルートの app/not-found.tsx は、notFound が呼ばれたときだけでなく、どのルートにも一致しない URL にアクセスしたときにも表示される。not-found.tsx は既定で Server Component なので、async にしてデータを取得できる。props は受け取らない。

自分の理解

拡張子は .jsx(.js)でもよい。

関連

出典