2026年5月20日

2026年5月20日

WordPressの404ページをカスタマイズする方法

はじめに

404エラーページはユーザーが存在しないURLにアクセスした際に表示されます。デフォルトのWordPressテーマの404ページはシンプルですが、検索フォームや人気記事を表示することでユーザーのサイト離脱を防げます。

症状・原因

  • デフォルトの404ページが味気ない
  • 404ページからサイト内の他コンテンツに誘導したい
  • 旧URLから新URLへリダイレクトしたい
  • 404の発生URLをログに記録したい

解決手順

ステップ1:404.phpを作成する

// 404.php
get_header();
?>
<main id="main" class="site-main error-404">

    <header class="page-header">
        <h1 class="page-title">404 - ページが見つかりません</h1>
        <p class="page-description">
            お探しのページは移動・削除されたか、URLが間違っている可能性があります。
        </p>
    </header>

    <div class="error-404-content">

        <!-- 検索フォーム -->
        <section class="error-search">
            <h2>サイト内を検索する</h2>
            <?php get_search_form(); ?>
        </section>

        <!-- 人気記事 -->
        <section class="error-popular">
            <h2>人気の記事</h2>
            <?php
            $popular_posts = new WP_Query([
                'posts_per_page'      => 5,
                'post_status'         => 'publish',
                'orderby'             => 'comment_count',
                'order'               => 'DESC',
                'ignore_sticky_posts' => true,
                'no_found_rows'       => true,
            ]);

            if ($popular_posts->have_posts()) :
            ?>
                <ul class="popular-posts-list">
                    <?php while ($popular_posts->have_posts()) : $popular_posts->the_post(); ?>
                        <li>
                            <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
                            <time><?php echo get_the_date(); ?></time>
                        </li>
                    <?php endwhile; ?>
                </ul>
                <?php wp_reset_postdata(); ?>
            <?php endif; ?>
        </section>

        <!-- カテゴリ一覧 -->
        <section class="error-categories">
            <h2>カテゴリ</h2>
            <?php
            wp_list_categories([
                'orderby'    => 'count',
                'order'      => 'DESC',
                'show_count' => true,
                'title_li'   => '',
                'number'     => 10,
            ]);
            ?>
        </section>

        <!-- トップへ戻るリンク -->
        <p class="back-to-home">
            <a href="<?php echo esc_url(home_url('/')); ?>" class="button">
                &larr; トップページへ戻る
            </a>
        </p>

    </div>

</main>
<?php get_footer();

ステップ2:旧URLを新URLにリダイレクトする

// functions.php
function mytheme_redirect_old_urls(): void {
    if (!is_404()) {
        return;
    }

    $request_uri = $_SERVER['REQUEST_URI'] ?? '';

    // URL変換マップ
    $redirects = [
        '/old-page/'          => '/new-page/',
        '/old-category/post/' => '/new-category/post/',
        '/wp-content/old/'    => '/wp-content/new/',
    ];

    foreach ($redirects as $old => $new) {
        if (str_starts_with($request_uri, $old)) {
            wp_redirect(home_url($new), 301);
            exit;
        }
    }
}
add_action('template_redirect', 'mytheme_redirect_old_urls');

ステップ3:404ログを記録する

// functions.php
function mytheme_log_404(): void {
    if (!is_404()) {
        return;
    }

    $log_file = WP_CONTENT_DIR . '/404-log.txt';
    $max_size = 1024 * 1024; // 1MB

    // ファイルサイズを確認(超過したらローテーション)
    if (file_exists($log_file) && filesize($log_file) > $max_size) {
        rename($log_file, $log_file . '.bak');
    }

    $log_entry = sprintf(
        "[%s] %s | Referer: %s | UA: %s\n",
        gmdate('Y-m-d H:i:s'),
        esc_url($_SERVER['REQUEST_URI'] ?? ''),
        esc_url($_SERVER['HTTP_REFERER'] ?? '-'),
        sanitize_text_field($_SERVER['HTTP_USER_AGENT'] ?? '-')
    );

    file_put_contents($log_file, $log_entry, FILE_APPEND | LOCK_EX);
}
add_action('wp', 'mytheme_log_404');

ステップ4:404ページのSEO設定

// functions.php: 404ページのメタタグを設定
function mytheme_404_noindex(): void {
    if (is_404()) {
        // robots meta を noindex に設定(Yoast SEO等が入っていない場合)
        echo '<meta name="robots" content="noindex, follow">' . "\n";
    }
}
add_action('wp_head', 'mytheme_404_noindex');

// HTTPステータスコードが正しく404になっているか確認
function mytheme_check_404_status(): void {
    if (is_404()) {
        status_header(404); // 明示的に404を設定
    }
}
add_action('wp', 'mytheme_check_404_status', 1);

注意事項

  • 404ページには必ずHTTPステータスコード 404 を返してください。200 OK を返す「ソフト404」はSEOに悪影響を及ぼします
  • リダイレクトは恒久的な移動には 301、一時的な移動には 302 を使ってください
  • 404ログファイルを wp-content/ 直下に置く場合、公開URLからアクセスできないよう .htaccess で保護してください

まとめ

404.php に検索フォーム・人気記事・カテゴリ一覧を配置してユーザーの離脱を防ぎます。旧URLのリダイレクトは template_redirect フックで wp_redirect(url, 301) を使います。404のHTTPステータスコードが正しく返されているか確認し、robotsnoindex に設定します。

お気軽にご相談ください

お見積りへ お問い合わせへ