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を一括修正の手順で解決します。