Menu

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のHTTPステータスコードを、非ストリーミングレスポンスの場合は404を返します。

app/not-found.tsx
TypeScript
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(実験的機能)

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.tsxapp/(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
TypeScript
// グローバルスタイルとフォントをインポート
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コンポーネントはいかなるプロップも受け入れません。

補足:予期されるnotFound()エラーをキャッチするだけでなく、ルートapp/not-found.jsapp/global-not-found.jsファイルはアプリケーション全体の一致しないURLを処理します。これはアプリで処理されないURLを訪問するユーザーがエクスポートされたUIを表示されることを意味します。

データ取得

デフォルトでは、not-foundはServer Componentです。データを取得して表示するためにasyncとしてマークできます。

app/not-found.tsx
TypeScript
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 Hooksを使用する必要がある場合は、代わりにクライアント側でデータを取得する必要があります。

メタデータ

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

補足:Next.jsはglobal-not-found.jsページを含む、404ステータスコードを返すページに対して自動的に<meta name="robots" content="noindex" />を注入します。

app/global-not-found.tsx
TypeScript
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が導入時期:実験的機能。
v13.3.0ルートapp/not-foundがグローバルな一致しないURLを処理。
v13.0.0not-foundが導入時期:。