―― Redirection × Block Theme × canonical redirect が起こす“複合災害”を真っ正面から解剖する
はじめに
WordPress の「/page/2/ が 404 になる」──検索すると事例は山ほどあるのに、自分のサイトでは Redirection プラグインを無効化したら直る、という謎挙動。根本治療の鍵は、Apache から JavaScript まで 5 層 を縦断しながら実行パスを追うことだった。
この記事では実際のデバッグログを交え、直アクセスだけ 404、内部リンクは大丈夫 という一見オカルトなバグを、シンプルな原因へと収束させるプロセスを共有する。
備忘録なので、楽しくもないし誰の為にもなりませんが、俺のために残します。

ねたばれすると、Redirectionに ^/.+/page/[0-9]+/?$ [F] っていう、
サイト全体の /page/N を 403/404 にするってアホなルール設定してたからだよ〜
- 1. はじめに
- 2. 第1章: WordPress深層部の動作原理
- 2.1. フック実行順序の真実
- 2.2. Block Theme のレンダリング機構
- 2.3. 条件フラグのライフサイクル
- 2.4. ここでフラグが崩れた瞬間に起こること
- 2.5. 要チェックポイント
- 3. 第2章 実戦デバッグ技術
- 3.1. HTTP レイヤーで確認
- 3.2. 二分探索式プラグイン切り分け
- 4. 第3章 プラグイン連携の闇
- 4.1. Redirection がページ遷移に影響する 3 つの仕組み ―― 機能・フック・副作用を早見で把握 ――
- 4.2. Interactivity API の落とし穴 ―― 同じ URL でも結果が変わる理由
- 5. 第4章 根本原因分析の思考法
- 5.1. 対症療法 vs 根本治療 — どちらを選ぶ?
- 5.1.1. 対症療法(力技で 200 にする)
- 5.1.2. 根本治療(拒否ルールそのものを除去)
- 5.2. まとめ
- 5.3. 制御層の優先順位
- 6. 第5章 教訓と予防策
- 6.1. デバッグの黄金律
- 6.2. アーカイブ系のリダイレクト不具合のバグフィックス
- 7. 犯人は自分
- 8. おわりに
第1章: WordPress深層部の動作原理
フック実行順序の真実
init → parse_request → pre_get_posts → wp
→ template_redirect → pre_handle_404
共に深淵に潜ったClaudeCodeくんの3行メモ
- pre_handle_404 は 404 判定を止められる最後の関所。
- redirect_canonical は 404 より前に走る。
- template_redirect ならまだ HTTP ステータスを書き換えられる。
Block Theme のレンダリング機構
ファイル | 役割 |
---|---|
template-canvas.php | 全ブロックテンプレートのエントリー |
archive.html | Query Loop を含み、実データを描画 |
inherit 属性 | メインクエリを継承する生命線 |
enhancedPagination | JS ナビゲーションと直接アクセスで挙動がズレる要因 |
条件フラグのライフサイクル
// pre_get_posts 時点
is_category() → true
is_paged() → true
// wp 時点(外部要因で破損)
is_category() → false // canonical redirect が潰す
is_paged() → false
ここでフラグが崩れた瞬間に起こること
$wp_query->posts
が空配列になり、後段のpre_handle_404
で 404 判定が確定- Block Theme 側は
wp-block-query-no-results
を描画し、404 レイアウトが優先表示される - Interactivity API での JS ナビゲーション時はフラグが壊れないため、直アクセスと結果が食い違う
要チェックポイント
redirect_canonical
で URL が書き換わっていないか- Redirection / SEO 系プラグインが
pre_handle_404
で 404 を強制していないか - Query Loop の
inherit
属性が false のまま保存されていないか
第2章 実戦デバッグ技術
add_action('pre_get_posts', function($q){
error_log('[PRE] cat='.(int)$q->is_category().' paged='.(int)$q->is_paged());
});
デバッグのポイント
- 1. pre_get_posts は メインクエリが初めて姿を現す 最速の地点。
- 2. ここで
is_category()
/is_paged()
をログに残してベースラインを確定させる。 - 3. 後続フックのログと差分を比較すれば、どの処理がフラグを壊したか が一発でわかる。
HTTP レイヤーで確認
curl -I https://mikaduki.info/category/laravel/page/2/
- X-Redirect-By: Redirection ← 犯人フラグ
- HTTP/2 404 ← Apache で弾かれている
- この時点で気づくべきだった。
二分探索式プラグイン切り分け
戦友ClaudeCodeくんのメモ
- 全部無効 → 正常 ⇒ プラグイン起因確定
- 半分有効 → 異常 ⇒ 範囲を半分に縮小
- Redirection 単独停止 → 正常 ⇒ 犯人特定
第3章 プラグイン連携の闇
Redirection がページ遷移に影響する 3 つの仕組み
―― 機能・フック・副作用を早見で把握 ――
何が動く? | 動く場所(フック/層) | 起こること・副作用 |
---|---|---|
404 ログ記録機能 | pre_handle_404 / template_redirect | $wp_query->is_404 = true / posts = [] → 画面が 404 に切り替わる |
動的リダイレクト機能 | redirect_canonical | Core が出す canonical 301 を上書き、独自 301/302 を優先 |
.htaccess 直書き(Apache モード) | Apache レイヤー(PHP 介さず) | サーバーが直接 301/403 を返す → 超高速だが GUI で無効化しないと即反映 |
👹 Redirectionが2面性発揮
Interactivity API の落とし穴 ―― 同じ URL でも結果が変わる理由
アクセス方法 | ブラウザ側で起こること | 画面に現れる結果 |
---|---|---|
内部リンクからの遷移 ( <a href="…"> をクリック) | Interactivity API が “ページ差し替え” だけを実行。 JS が wp-block-query-no-results 要素を 非表示 にして投稿一覧だけを残す。 | 正常表示(404 ブロックは見えない) |
URL を直接入力/リロード | サーバー側でフルレンダリング。 テンプレートが 404 ブロック + 投稿一覧 を両方出力するが、JS はまだ実行されていない。 | 404 レイアウトが先に描画 → 投稿一覧が隠れ、404 画面に見える |
第4章 根本原因分析の思考法
対症療法 vs 根本治療 — どちらを選ぶ?
対症療法(力技で 200 にする)
add_filter( 'status_header', fn( $h ) => str_replace( '404', '200', $h ) );
メリット
- コード 1 行で即反映
- テーマやプラグインの改変が一切不要
デメリット / 落とし穴
- HTML には 404 ブロックが残る → 検索エンジンには 404 ページ扱い
- キャッシュや AMP では 404 画面が再浮上することも
- 別 URL で同症状が再発しやすい
根本治療(拒否ルールそのものを除去)
- Redirection の 拒否正規表現 を GUI で「無効化」または「削除」 (ルール一覧 → チェック → Disable / Delete → 保存)
メリット
- HTTP と HTML が完全に一致
- 同じパターンの URL で問題が再発しない
- SEO 的にも正しい 200 ページとしてクロールされる
デメリット / 注意点
- ルールを見直す手間が少し必要
- 「ページネーションは 1 ページ目に統合したい」場合は 301 で /page/n → / にリダイレクト する追加設定が要る
まとめ
- 今日中にとにかく 404 表示を消したい → 対症療法で応急処置
- SEO・再発防止を重視したい → 根本治療を選ぶのが最終的にラク
制御層の優先順位
- Apache/Nginx (.htaccess) – 最強
- WordPress Core (PHP)
- プラグイン
- テーマ (Block)
- JavaScript – 最弱
第5章 教訓と予防策
デバッグの黄金律
- ログを信じすぎるな – HTTP 200 でもブラウザは 404 を描くことがある
- SEO 系プラグインは常に疑え – canonical と 301/302 を重ねるから
- レイヤーを意識 – Apache → PHP → JS の順で確認
アーカイブ系のリダイレクト不具合のバグフィックス
- Query Loop では
inherit:true
を明示 - リダイレクト系プラグイン導入後は .htaccess 差分チェック
- 404 ルールを設ける前に 正規表現がページネーションを潰さないかテスト
犯人は自分
Redirection を外そうかと腹を括り、エクスポート機能で .htaccess 用ルールを吐き出してみたら──
^/.+/page/[0-9]+/?$ [F]
ページネーションをまるごと葬る “[F] 行” が、なんと最上段に鎮座。
おかげで原因が即座に特定でき、その 1 行を削除して無事復旧しました。
おわりに
パーマリンクを変更して以降、カテゴリーページの 2 ページ目に進めない不具合がずっと残ったままでした。閲覧が少ないこともあり後回しにしていたのですが、休日にまとまった時間が取れたうえに ChatGPT-o3 と ClaudeCode という新兵器を入手したので、一気に片付けようと着手。ところが想像以上に手こずる結果に――。
「パッチを当てれば済むだろ」と高をくくっていたら、結局はテーマの深部まで手を入れる羽目に。
「もう限界、Apache のリダイレクトで力技に切り替えよう」と覚悟を決めた瞬間、あの page/n
禁止ルール が目に飛び込んできた──まるで見えざる神の手に救われた気分だった・・・。
この体験で痛感したのは、「いきなりコードの深淵に飛び込まない」こと。
まずは 設定・プラグイン・サーバー層 を一通り洗い、ログを取り、可能性を潰してから手を入れる──それだけで余計な沼を避けられます。
私のしくじりが、みなさんの“時間節約ハック”になれば幸いです。
-
ページネーションが 404 になるとき、まず何を確認すればいい?
-
1) .htaccess に /page/ 系の拒否ルールがないか
2) redirect_canonical を潰すプラグイン(Redirection など)が動いていないか
3) Block Theme の Query Loop で inherit:true が設定されているか、の順でチェックすると早いです。
-
Apache (.htaccess) モードに切り替えるメリットは?
-
- 301/302 を Apache が直接処理 → PHP 起動ゼロで高速
- WordPress フックを通らないため canonical/404 介入バグと無縁
- ルール追加は GUI で OK、保存すると .htaccess が即更新
-
page/n 絶許ルール の見つけ方は?
-
Redirection 画面の検索ボックスに page/[0-9] と入力。
-
page/n 絶許ルール の見つけ方は?
-
Redirection 画面の検索ボックスに page/[0-9] と入力。
-
対症療法で一瞬だけ 404 を消すには?
-
add_filter( 'status_header', fn( $h ) => str_replace( '404', '200', $h ) ); # 応急処置。HTML には 404 ブロックが残るので SEO 目的なら根本治療を。
コメントを残す