カスタム404ページの設定と正しい実装方法
本物の404を返し、ソフト404のシグナルを避け、訪問者に役立つ導線を用意する方法。フレームワークとサーバー設定の両方で解説します。
ユーザーがリンク切れのURLにアクセスしたら、サーバーは404 Not Foundのステータスを返す必要があります。ところが実際のプロジェクトでは、このルールが驚くほど頻繁に破られています。CMSが200 OKを返す、リダイレクトでトップページに飛ばす、「404ページ」のコードは正しくても画面が真っ白になる、といった具合です。どれもSEOとユーザーの両方にとって別々の問題です。
正しく設定した404ページは、3つの問題を同時に解決します。URLが存在しないことをGoogleに伝えます。ユーザーをサイト内にとどめ、目的のセクションへ案内します。無駄なクロールからクロールバジェットを守ります。以下、順に見ていきます。
404ページとは
404 Not Foundは、リクエストされたリソースが存在しないときにサーバーが返すHTTPレスポンスコードです。サーバーは正常に動作していてルーティングも解決できたものの、該当するドキュメントがない、という意味になります。この点で、500(サーバーエラー)や503(サービス利用不可)とは異なります。
カスタム404がないサイト
ほとんどのサイトは、ナビゲーションつきの独自ページではなく、プラットフォーム標準の404を表示している
インデックス削除までの期間
正しく404を返しているURLは、通常、数週間でGoogleのインデックスから削除される。Search Consoleで早められる
最も多い間違い
CMSが404ではなく200 OKを返すと、Googleが空のページをインデックスに登録し、サイトのテーマの一貫性が薄れる
削除が早い
Googleは410(Gone)を404よりかなり早くインデックスから削除する。大量のページを削除するときに使う
404ページは2つのレベルで存在します。HTTPレベルは、検索クローラーが見るヘッダーのレスポンスコードです。表示レベルは、ユーザーが見るHTMLコンテンツです。どちらも同じく重要です。HTTPコードの誤りはSEOの問題で、表示の不備はUXの問題です。
最重要ルール:必ずHTTP 404を返す
最初で最も重要なルールは、エラーページがHTTPステータス404(または410)を返すことです。200は返してはいけません。これを「ハード404」と呼び、「ソフト404」と区別します。
どのページのHTTPステータスも、ブラウザーで直接確認できます。F12 → Network → ページを再読み込み → 最初のリクエストを選択 → Status列を見ます。ターミナルならcurlでも確認できます。
# Check HTTP status of a page
curl -s -o /dev/null -w "%{http_code}" https://example.com/non-existent-url
# Expected output: 404
# Check full response headers
curl -I https://example.com/non-existent-urlソフト404と410の違い
「ハード404」のほかに、実務で混同されやすいものが2つあります。ソフト404と、410ステータスです。削除したページを正しく扱うには、この違いの理解が欠かせません。
| ステータス | HTTPコード | Googleにとっての意味 | 使う場面 |
|---|---|---|---|
| ハード404 | 404 | リソースが見つからない。数週間でGoogleのインデックスから削除される | ページを削除した、またはもともと存在しない |
| ソフト404 | 200(誤り) | Googleが「成功した」レスポンスと見なし、空のコンテンツをインデックスに登録する | 使わない。意図した選択ではなく、実装のバグ |
| Gone | 410 | リソースを恒久的に削除した。Googleは404よりかなり早くインデックスから削除する | 大量のページ削除(旧商品、不要になったセクション) |
Googleは、404のURLからトップページや無関係な別ページへのリダイレクトも、ソフト404と見なします。検索エンジンから見ると、ユーザーはAを探してBにたどり着いたのに、Bの内容は検索クエリへの答えになっていません。これでリダイレクト先ページの品質シグナルが下がります。
404ページに入れる要素
404ページに着いたユーザーは、すでに軽くいらだっています。ページの役割は、そのいらだちを和らげ、次に何をすればよいかを明確に示すことです。効果的な404ページは、決まった構成になっています。
わかりやすいエラーメッセージ
状況を平易な言葉で説明します。「ページが見つかりません」「このページは存在しないようです」といった表現です。画面上の文言には、専門用語やエラーコードを使いません。
検索ボックス
404ページで最も効果的な要素です。ユーザーは探しているものをすでに知っています。Googleに戻らなくても、その場で探せるようにします。
主要セクションへのナビゲーション
トップページや人気のセクション、サイトマップへのリンクです。ユーザーが現在地をつかみ、サイト内の移動を続けられます。
404ページでやってはいけないこと:JavaScript(window.location.href = '/')でユーザーを自動的にトップページへ移動させることです。Googleはこれをソフト404と見なすことがあります。ユーザーが期待したのはAなのに、Bに飛ばされ、内容は無関係だからです。404のURLからサーバー側で301リダイレクトするのは、本当に代わりになるページがある場合に限ります。
実装:Next.js、Nginx、Apache
カスタム404ページの設定方法は、技術スタックによって異なります。ここでは、特によく使われる3つの構成を取り上げます。Next.js App Router、Nginx、Apacheです。
Next.js App Router
Next.js 13以降のApp Routerでは、app/ディレクトリ内のnot-found.tsxファイルでカスタム404ページを作成します。i18n(next-intlなど)を使う場合、ファイルはapp/[locale]/に置きます。
// app/[locale]/not-found.tsx
import Link from 'next/link';
export default function NotFound() {
return (
<main style={{ textAlign: 'center', padding: '4rem 1rem' }}>
<h1>404 — Page Not Found</h1>
<p>The link may be outdated or the address was mistyped.</p>
<Link href="/">Back to homepage</Link>
</main>
);
}
// Next.js automatically returns HTTP 404 for this file.404をプログラムから生成する場合(動的ルートapp/[locale]/blog/[slug]/page.tsxなど)は、next/navigationのnotFound()関数を使います。この関数を呼ぶとレンダリングを即座に中断し、HTTP 404を返してnot-found.tsxを表示します。
// app/[locale]/blog/[slug]/page.tsx
import { notFound } from 'next/navigation';
import { getArticleDoc } from '@/messages/blog-articles/registry';
export default async function ArticlePage({ params }: { params: { slug: string } }) {
const article = getArticleDoc(params.slug);
// If slug does not exist — return HTTP 404 and render not-found.tsx
if (!article) {
notFound();
}
return <ArticleRenderer article={article} />;
}pages/404.tsxを作成すると、Next.jsが自動的にそのページへルーティングし、HTTP 404を返します。Pages RouterではnotFound()関数は使えません。代わりに、getStaticPropsかgetServerSidePropsで{ notFound: true }を返します。// Pages Router: pages/blog/[slug].tsx (legacy approach)
export async function getServerSideProps({ params }) {
const article = getArticleDoc(params.slug);
if (!article) {
// Next.js will return HTTP 404 and show pages/404.tsx
return { notFound: true };
}
return { props: { article } };
}Nginx
Nginxでは、serverブロック内のerror_pageディレクティブでカスタム404ページを設定します。404.htmlが指定したパスに存在するか、そのファイルを返す際に200への内部リダイレクトが起きていないかを確認します。
server {
listen 80;
server_name example.com;
root /var/www/html;
# Custom page for 404 errors
error_page 404 /404.html;
# The location for the file itself — returns 404, not 200
location = /404.html {
internal;
}
# Custom pages for other errors
error_page 500 502 503 504 /50x.html;
location = /50x.html {
internal;
}
}internalディレクティブは、/404.htmlへの外部からの直接アクセスを防ぎます。ページはエラーレスポンスとしてのみ表示されます。これがないと、/404.htmlを直接開いて200が返され、コンテンツの重複が生じます。Apache / .htaccess
Apacheでは、ErrorDocumentでカスタム404を設定します。メイン設定ファイルでも.htaccessでも設定できます。
# .htaccess in the site root
# Custom 404 page
ErrorDocument 404 /404.html
# You can also point to a PHP file
# ErrorDocument 404 /404.php
# Custom pages for other errors
ErrorDocument 403 /403.html
ErrorDocument 500 /500.html
# Enable mod_rewrite for SPA routing
<IfModule mod_rewrite.c>
RewriteEngine On
# For React/Vue SPA: all non-existent routes → index.html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ /index.html [L]
</IfModule>index.htmlで返すと、検索エンジンが存在しないページをインデックスに登録します。対策は2つあります。SPA側で、404ページに<meta name="robots" content="[noindex](/glossary/noindex)">をクライアント側で追加するか、SSR/SSGで適切なHTTPステータスコードを返します。PHP(WordPressなどのCMS)
WordPressのカスタム404ページは、テーマ内の404.phpファイルです。パーマリンクが正しく設定されていれば、WordPressは存在しないURLに対して自動的にHTTP 404を返します。CMSが404ではなく200を返す場合、原因は通常.htaccessかサーバー設定にあります。
<?php
// themes/your-theme/404.php
// WordPress automatically returns HTTP 404
get_header();
?>
<main class="error-404">
<h1>Page Not Found</h1>
<p>Try using search:</p>
<?php get_search_form(); ?>
<p>Or return to the <a href="<?php echo home_url(); ?>">homepage</a>.</p>
</main>
<?php
get_footer();リンク切れの発見と修正
404ページを正しく設定するのは、作業の半分にすぎません。残りの半分は、存在しないページを指すリンクをすべて見つけて解消することです。インデックスに404が現れる主な原因は、リンク切れです。
Search Console →「インデックス作成」→「ページ」→「見つかりませんでした(404)」を開きます。無料で最も網羅的な情報源です。表示されるのは、Googleがクロール中に見つけた404だけで、SEOに直結するものばかりです。
Screaming Frog SEO Spiderでサイトをクロールします。フィルターはResponse Codes → 4xxです。404のURLだけでなく、リンク元のページもわかります。どのページにリンク切れがあるかを正確に把握できます。
ログには、Googleがまだ見つけていないものも含め、すべてのリクエストが記録されています。grep ' 404 ' access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head -20で、404を返しているURLの上位20件がわかります。
見つけた404ごとに、次の3つから選びます。似たページがあれば、該当する代替URLへの301を設定します。そのURLを指す内部リンクをすべて削除します。リンクが1本もなければ、404のままにします(Googleが自動的にインデックスから削除します)。
# Find top-20 broken URLs in Nginx/Apache logs
grep ' 404 ' /var/log/nginx/access.log \
| awk '{print $7}' \
| sort \
| uniq -c \
| sort -rn \
| head -20
# Example output:
# 143 /old-product-page
# 87 /blog/removed-article
# 34 /wp-login.php (attack attempts — not critical)404エラーの監視
一度きりの監査は有効ですが、新しい404は絶えず発生します。ページ名の変更、商品の削除、外部サイトからの存在しないURLへのリンクなどが原因です。定期的な監視を設定しておくことが重要です。
| ツール | 監視対象 | 頻度 | 無料 |
|---|---|---|---|
| Google Search Console | Googlebotがクロール中に見つけた404 | 毎日更新 | 可 |
| Screaming Frog+スケジューラー | サイト全体のクロールで見つかったすべての404 | 週次/月次 | 500 URLまで |
| サーバーログ(goaccess、awstats) | access.logにあるすべての404をリアルタイムで確認 | リアルタイム | 可 |
| Ahrefs / Semrushサイト監査 | 404と、404を指す外部からの被リンク | 週次の自動チェック | 有料 |
| UptimeRobot / Better Uptime | 主要URLの稼働監視 | 1〜5分ごと | 基本プランは無料 |
大規模サイト(1万ページ以上)では、サーバーログが特に役立ちます。ボットやユーザー、スクリプトを含む、リクエストの100%を網羅しているからです。Search Consoleに表示されるのは、Googlebotがクロールで見つけたものだけで、全体の一部にすぎません。
正しい404ページのチェックリスト
HTTPステータス
- 404ページがHTTPステータス404を返している(curlまたはDevToolsで確認済み)
- ソフト404がない:エラーメッセージのページが200 OKを返していない
- 存在しないURLからトップページへのJavaScriptリダイレクトがない
- 代わりのページがない大量削除ページには410 Goneを使っている
- 301リダイレクトは、関連性のある代替ページがあるURLにだけ設定している
ページの内容
- 専門用語を使わない、わかりやすいエラーメッセージがある
- 検索ボックス、またはサイト内検索へのリンクがある
- トップページへのリンクがある
- 人気のセクションやカテゴリーへのリンクが2〜4件ある
- サイトのブランドに合ったデザインにしている(ヘッダー、フッター、フォント)
実装
- Next.js:not-found.tsxを作成し、存在しないスラッグでnotFound()を呼んでいる
- Nginx:error_page 404ディレクティブを設定し、404.htmlをinternalにしている
- Apache:.htaccessまたはメイン設定にErrorDocument 404を設定している
- WordPress:有効なテーマに404.phpがある
- SPA(SSRなしのReact/Vue):404ページでクライアント側からnoindexのmetaタグを追加している
監視
- Google Search Consoleを接続し、メールアラートを設定している
- Screaming Frogなどで定期的にクロールしている(少なくとも月1回)
- サーバーログにアクセスでき、アクセスの多いサイトでは分析している
- 404のURLを指す内部リンクをすべて見つけて修正した
yourdomain.com/test-404-checkなど)を開き、DevToolsのNetworkで最初のリクエストのステータスを見ます。200なら、ソフト404になっているため、サーバー設定を修正する必要があります。よくある質問
監査や開発の場面でよく出る、404ページの設定に関する質問に答えます。
404ページにnoindexタグは必要ですか?
Googleで上位表示されていたページが404を返すようになったら、どうすればよいですか?
404ページをデザイン性の高いブランドページにしてもよいですか?
存在しないURLすべてで、404ページは同じでよいですか?
クロールバジェットとは何ですか?404はどう消費しますか?
Check it with SpiderHead
Free and local: run the audit on your own machine.



