2026年9月21日

2026年9月21日

WordPressで投稿・固定ページが404エラーになる問題を解決する方法

はじめに

WordPressで記事を公開したのにURLにアクセスすると「お探しのページは見つかりませんでした」という404エラーが返る・管理画面のパーマリンク設定を変更したら全てのページが404になった・カスタム投稿タイプをregister_post_type()で登録したがアーカイブページやシングルページにアクセスすると404になる・ステージング環境から本番環境に移行した後から全ページが404になったといった問題は、.htaccessのリライトルール・パーマリンクのフラッシュ忘れ・ApacheのAllowOverride設定が原因です。

症状・原因

  • .htaccessにWordPress用のリライトルールが書かれていない、または破損している
  • Apacheの設定でAllowOverride Allが設定されておらず.htaccessが無視されている
  • register_post_type()追加後にパーマリンクをフラッシュしていない
  • Nginxを使用しているためApache用の.htaccessが機能しない

解決手順

ステップ1:404エラーの原因を診断する

# パーマリンク設定を確認
wp eval "
global \$wp_rewrite;
echo 'permalink_structure: ' . get_option('permalink_structure') . PHP_EOL;
echo 'rewrite_rules count: ' . count(\$wp_rewrite->rules ?? []) . PHP_EOL;
"

# .htaccess の内容を確認
wp eval "echo file_get_contents(ABSPATH . '.htaccess');"

# パーマリンクをフラッシュして .htaccess を再生成
wp rewrite flush --hard

# Apacheの設定を確認
apachectl -t
grep -r "AllowOverride" /etc/apache2/sites-enabled/

ステップ2:.htaccess を正しく設定する

# WordPress 標準の .htaccess(手動で書き直す場合)
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
# wp-cli で .htaccess を再生成
wp rewrite flush --hard

# または PHP で直接再生成
wp eval "
global \$wp_rewrite;
\$wp_rewrite->flush_rules(true);  // true = .htaccess に書き込む
echo 'Rules flushed.' . PHP_EOL;
"

ステップ3:カスタム投稿タイプの404を解決する

// register_post_type() を正しく設定
register_post_type('news', [
    'label'       => 'ニュース',
    'public'      => true,
    'has_archive' => true,        // アーカイブページを有効化
    'rewrite'     => [
        'slug'       => 'news',   // URLスラッグ
        'with_front' => false,    // パーマリンク構造の前置きを付けない
        'feeds'      => true,
        'pages'      => true,
    ],
    'supports'    => ['title', 'editor', 'thumbnail', 'excerpt'],
]);

// プラグイン/テーマ有効化時にパーマリンクをフラッシュ
register_activation_hook(__FILE__, function(): void {
    // register_post_type() を先に呼ぶ
    register_my_post_types();
    flush_rewrite_rules();
});

ステップ4:Nginx での404を解決する

# Nginx の設定(/etc/nginx/sites-enabled/example.conf)
server {
    listen 80;
    server_name example.com;
    root /var/www/html;
    index index.php;

    # WordPress のパーマリンクに必要な設定
    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    # アップロードファイルへの PHP 実行を禁止
    location ~* /uploads/.*\.php$ {
        deny all;
    }
}

ステップ5:特定ページの404を解決する

// 固定ページのスラッグが重複している場合の確認
wp eval "
\$pages = get_posts([
    'post_type'   => ['post', 'page', 'news'],
    'post_status' => 'publish',
    'name'        => 'about',  // 問題のスラッグ
    'numberposts' => -1,
]);
foreach (\$pages as \$p) {
    echo \$p->post_type . ': ' . \$p->ID . ' - ' . \$p->post_title . ' - ' . get_permalink(\$p->ID) . PHP_EOL;
}
"

// カスタムリライトルールを追加
add_action('init', function(): void {
    add_rewrite_rule(
        '^custom-path/([^/]+)/?$',
        'index.php?custom_param=$matches[1]',
        'top'
    );
    add_rewrite_tag('%custom_param%', '([^&]+)');
});
# 移行後の URL を一括修正
wp search-replace 'https://staging.example.com' 'https://example.com' \
    --skip-columns=guid --report-changed-only
wp rewrite flush --hard

注意事項

  • パーマリンク設定を変更した後は必ず「変更を保存」ボタンを押してパーマリンクをフラッシュしてください。これをせずに投稿URLを変更するとすべてのページが404になります
  • ApacheでAllowOverride Noneが設定されている場合、.htaccessは完全に無視されます。ホスティング会社の管理画面またはVirtualHostの設定でAllowOverride Allに変更してください
  • register_post_type()をinitフックより前(プラグインのトップレベルなど)で呼び出すと動作しません。必ずinitフックで登録してください

まとめ

WordPress 404エラーの解決は①wp rewrite flush --hardでパーマリンクをフラッシュして.htaccessを再生成・get_option('permalink_structure')でパーマリンク設定を確認・apachectl -tで設定ファイルの構文チェック、②.htaccessにRewriteEngine Onから始まるWordPress標準のリライトルールを正確に記述・AllowOverride AllをApache設定に追加、③register_post_type()のhas_archive=true・rewrite配列でアーカイブURLを設定・register_activation_hook()でフラッシュ、④Nginxはtry_files $uri $uri/ /index.php?$argsでWordPressのパーマリンクに対応、⑤スラッグの重複をget_posts()で確認・add_rewrite_rule()でカスタムルールを追加・移行後はwp search-replaceでURLを一括修正の手順で解決します。

お気軽にご相談ください

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