1. ホーム
  2. Next.js

【Next.js】not-found.tsx で404ページを作る方法|notFound() 関数も解説

Share

存在しないURLにアクセスされたときや、指定されたデータが見つからなかったときに表示する「404 ページ」。Next.js の App Router では、not-found.tsx という特別なファイルを置くだけで、自分のサイトに合ったデザインの404ページを用意できます。さらに notFound() 関数を使えば、コードの中から「これは見つからなかった」と宣言して404ページを表示できます。この記事では、両者の使い方と、セグメントごとに出し分ける方法まで、初心者向けに解説します。

not-found.tsx とは

not-found.tsx は、App Router で「見つからなかった」ときに表示されるUIを定義する特別なファイルです。app フォルダの中に置くと、次の2つの場面で自動的に使われます。1つは、後述する notFound() 関数が呼ばれたとき。もう1つは、どのルートにも一致しないURLにアクセスされたとき(app 直下に置いた場合)です。まずは基本の作り方から見ていきましょう。

not-found.tsx を作る

app/not-found.tsx を作成し、404ページとして表示したい内容を返すコンポーネントを書きます。ふつうのページと同じように JSX を返すだけです。

app/not-found.tsx
import Link from "next/link";

export default function NotFound() {
  return (
    <div>
      <h1>404 - ページが見つかりません</h1>
      <p>お探しのページは存在しないか、移動された可能性があります。</p>
      <Link href="/">トップページに戻る</Link>
    </div>
  );
}

app 直下に置いた not-found.tsx は、サイト全体の「どこにも一致しないURL」に対する404ページになります。デフォルトの素っ気ない404画面が、自分でデザインした画面に置き換わります。

notFound() で404を出す

URLの形は正しくても、「そのIDの投稿が存在しない」ようなケースがあります。このときは next/navigationnotFound() 関数を呼ぶと、その場で処理を中断して not-found.tsx を表示できます。動的ルーティングのページでよく使うパターンです。

app/posts/[id]/page.tsx
import { notFound } from "next/navigation";

async function getPost(id: string) {
  const res = await fetch(`https://example.com/api/posts/${id}`);
  if (!res.ok) return null; // 見つからなかった
  return res.json();
}

export default async function PostPage({
  params,
}: {
  params: Promise<{ id: string }>;
}) {
  const { id } = await params;
  const post = await getPost(id);

  // データが無ければ 404 ページを表示する
  if (!post) {
    notFound();
  }

  return <h1>{post.title}</h1>;
}

notFound() は呼び出すと内部で例外を投げて処理を止めるため、その後のコードは実行されません。return notFound() と書かなくても、それより下(post.title を使う部分)には到達しない仕組みです。この関数のおかげで、「データが無ければ404」というよくある処理をすっきり書けます。

セグメントごとに404を出し分ける

not-found.tsxapp 直下だけでなく、フォルダ(ルートセグメント)ごとに置けます。たとえば app/blog/not-found.tsx を用意すると、blog 配下で notFound() が呼ばれたときには、ブログ専用の404ページが表示されます。近い階層のものが優先されるため、セクションごとに雰囲気を変えたいときに便利です。

ファイルの場所使われる場面
app/not-found.tsxサイト全体の404(一致しないURL全般)
app/blog/not-found.tsxblog 配下で notFound() が呼ばれたとき

なお、存在しないURL全般に対して app 直下以外の not-found.tsx を割り当てたい場合は、キャッチオールルート([...slug])と組み合わせて notFound() を呼ぶ、といった作り方をします。まずは app/not-found.tsx を1つ用意しておけば、サイト全体の404はカバーできます。

まとめ

Next.js の App Router では、not-found.tsx を置くだけで独自の404ページを用意できます。app 直下に置けばサイト全体の404になり、フォルダごとに置けばその配下専用の404ページにできます。データが見つからないときは next/navigationnotFound() を呼べば、その場で処理を止めて404ページを表示できます。動的ルーティングで「存在しないIDにアクセスされた」ケースは頻繁に起きるので、notFound()not-found.tsx をセットで用意しておくとよいでしょう。

参考ページ