コンテンツにスキップ

not-found.js

Next.js は、見つからないケースを処理するための 2 つの規約を提供しています。

  • not-found.js: ルートセグメントで notFound 関数を呼び出した場合に使用されます。
  • global-not-found.js: アプリケーション全体で一致しないルートに対するグローバルな 404 ページを定義するために使用されます。これはルーティングレベルで処理され、レイアウトやページのレンダリングには依存しません。

not-found.js

not-found ファイルは、ルートセグメント内で notFound 関数がスローされた場合に UI をレンダリングするために使用されます。カスタム UI を提供するだけでなく、Next.js はストリーミング応答の場合は 200、非ストリーミング応答の場合は 404 の HTTP ステータスコードを返します。

app/not-found.tsx
import Link from 'next/link'
 
export default function NotFound() {
  return (
    <div>
      <h2>Not Found</h2>
      <p>Could not find requested resource</p>
      <Link href="/">Return Home</Link>
    </div>
  )
}

global-not-found.js (experimental)

global-not-found.js ファイルを使用すると、アプリケーション全体に対して 404 ページを定義できます。ルートレベルで機能する not-found.js とは異なり、これは要求された URL がどのルートにも一致しない場合に使用されます。Next.js はレンダリングをスキップし、直接このグローバルページを返します。

global-not-found.js ファイルは、アプリの通常のレンダリングをバイパスするため、404 ページに必要なグローバルスタイル、フォント、その他の依存関係をインポートする必要があります。

知っておくと良いこと: グローバルスタイルの小さいバージョンと、よりシンプルなフォントファミリを使用すると、このページのパフォーマンスが向上する可能性があります。

global-not-found.js は、layout.jsnot-found.js の組み合わせで 404 ページを構築できない場合に役立ちます。これは 2 つのケースで発生する可能性があります。

  • アプリケーションに複数のルートレイアウトがある場合 (例: app/(admin)/layout.tsx および app/(shop)/layout.tsx)、グローバル 404 を構成するための単一のレイアウトが存在しません。
  • ルートレイアウトがトップレベルの動的セグメント (例: app/[country]/layout.tsx) を使用して定義されているため、一貫した 404 ページを構成することが困難になります。

有効にするには、next.config.tsglobalNotFound フラグを追加します。

next.config.ts
import type { NextConfig } from 'next'
 
const nextConfig: NextConfig = {
  experimental: {
    globalNotFound: true,
  },
}
 
export default nextConfig

次に、app ディレクトリのルートにファイルを作成します: app/global-not-found.js

app/global-not-found.tsx
// Import global styles and fonts
import './globals.css'
import { Inter } from 'next/font/google'
import type { Metadata } from 'next'
 
const inter = Inter({ subsets: ['latin'] })
 
export const metadata: Metadata = {
  title: '404 - Page Not Found',
  description: 'The page you are looking for does not exist.',
}
 
export default function GlobalNotFound() {
  return (
    <html lang="en" className={inter.className}>
      <body>
        <h1>404 - Page Not Found</h1>
        <p>This page does not exist.</p>
      </body>
    </html>
  )
}

not-found.js とは異なり、このファイルは <html> および <body> タグを含む完全な HTML ドキュメントを返す必要があります。

リファレンス

Props

not-found.js または global-not-found.js コンポーネントは、いかなる props も受け取りません。

知っておくと良いこと: 予想される notFound() エラーをキャッチするだけでなく、ルート app/not-found.js および app/global-not-found.js ファイルは、アプリケーション全体で一致しない URL を処理します。つまり、アプリで処理されない URL にアクセスしたユーザーには、エクスポートされた UI が表示されます。

Data Fetching

デフォルトでは、not-found は Server Component です。async としてマークすることで、データの取得と表示が可能です。

app/not-found.tsx
import Link from 'next/link'
import { headers } from 'next/headers'
 
export default async function NotFound() {
  const headersList = await headers()
  const domain = headersList.get('host')
  const data = await getSiteData(domain)
  return (
    <div>
      <h2>Not Found: {data.name}</h2>
      <p>Could not find requested resource</p>
      <p>
        View <Link href="/blog">all posts</Link>
      </p>
    </div>
  )
}

usePathname のような Client Component フックを使用してパスに基づいてコンテンツを表示する必要がある場合は、代わりにクライアントサイドでデータを取得する必要があります。

Metadata

global-not-found.js の場合、metadata オブジェクトまたは generateMetadata 関数をエクスポートして、404 ページの <title><meta>、およびその他の head タグをカスタマイズできます。

知っておくと良いこと: Next.js は、404 ステータスコードを返すページ (global-not-found.js ページを含む) に <meta name="robots" content="noindex" /> を自動的に挿入します。

app/global-not-found.tsx
import type { Metadata } from 'next'
 
export const metadata: Metadata = {
  title: 'Not Found',
  description: 'The page you are looking for does not exist.',
}
 
export default function GlobalNotFound() {
  return (
    <html lang="en">
      <body>
        <div>
          <h1>Not Found</h1>
          <p>The page you are looking for does not exist.</p>
        </div>
      </body>
    </html>
  )
}

バージョン履歴

バージョン変更履歴
v15.4.0global-not-found.js が導入されました (experimental)。
v13.3.0ルート app/not-found がグローバルで一致しない URL を処理します。
v13.0.0not-found が導入されました。