コンテンツへスキップ

WordPress の rewrite rules を再生成(flush)する場面 — パーマリンク変更後や新しい投稿タイプで 404 になるとき

「カスタム投稿タイプを追加したら、一覧も個別ページも 404 になった」「パーマリンク構造を変えたら、一部の URL だけ表示されない」。WordPress の保守でよく出会う症状で、原因が rewrite rules(書き換えルール)が古いまま であることは少なくありません。

この記事では、rewrite rules が何で、どこに保存され、どんな場面で再生成(flush)が必要になるのかを整理します。WordPress 本体の一般的な仕組みの解説で、特定の製品に依存した話ではありません。

補足: Apache の .htaccess と mod_rewrite の基本は、別記事の「.htaccess と mod_rewrite のルール」で扱っています。この記事は、その内側にある WordPress 自身のルール の話です。

2つの「書き換え」を分けて考える

WordPress の URL 処理には、役割の違う書き換えが2段あります。

段 担当 役割
1段目 Web サーバー(.htaccess など) 実在しないファイル・ディレクトリへのアクセスを index.php に渡す
2段目 WordPress 本体(rewrite rules) index.php に届いた URL を、どの投稿・アーカイブかのクエリに変換する

たとえば /news/2026/hello/ というアクセスは、1段目で index.php に渡され、2段目で「投稿タイプ news のスラッグ hello」といった内部クエリに解釈されます。1段目が正しくても、2段目のルールに該当がなければ WordPress は 404 を返します。 「flush が必要」と言われるのは、主にこの2段目の話です。

rewrite rules はどこにあるのか

2段目のルールは、wp_options テーブルの rewrite_rules というオプションに、正規表現と内部クエリの対応表として保存されています。リクエストのたびに全ルールを組み立て直すと負荷が大きいため、一度組み立てた結果をデータベースに置いておく設計です。

ここに落とし穴があります。ルールの元になる登録(投稿タイプ、タクソノミー、パーマリンク構造)を変えても、保存済みの rewrite_rules は自動では書き換わりません。 古い対応表のまま動き続け、新しい URL に対応する行がないので 404 になります。これを作り直す操作が flush です。

flush が必要になる主な場面

  1. パーマリンク構造を変えた(または変えようとした)とき
    設定の「パーマリンク」画面で構造を保存すると、WordPress はルールを作り直します。
  2. カスタム投稿タイプやカスタムタクソノミーを追加・変更したとき
    register_post_type() や register_taxonomy() の rewrite 引数(スラッグなど)を変えると、対応するルールが変わります。
  3. ルールを追加するプラグインを有効化・無効化したとき
    独自の URL(エンドポイントなど)を持つプラグインは、有効化の時点でルールの再生成が必要です。
  4. サイトを別の環境へ移したとき
    ドメインや設置ディレクトリが変わった場合、ルールの再確認が要ることがあります。
  5. .htaccess が失われた・上書きされたとき
    次の節で述べる「ハード」な再生成が関係します。

ソフトflushとハードflush

WordPress の関数 flush_rewrite_rules() は、引数 $hard で挙動が変わります。

  • ソフト($hard = false): データベースの rewrite_rules だけを作り直す。
  • ハード($hard = true・既定値): 加えて、Apache 環境では .htaccess の WordPress 用ブロックも書き直す(書き込み権限があり、mod_rewrite が使える設定の場合)。

管理画面の「パーマリンク」画面で「変更を保存」を押す操作は、実質的にこの再生成にあたります。WP-CLI では次のように使い分けられます。

# 現在のルールを一覧で確認する
wp rewrite list --format=table

# データベース側だけを作り直す(ソフト)
wp rewrite flush

# .htaccess も書き直す(ハード)
wp rewrite flush --hard

# パーマリンク構造を設定する(保存時にルールも更新される)
wp rewrite structure '/%postname%/'

画面操作ができない状況や、複数サイトを順に確認したいときは、wp rewrite list で「期待する URL のルールが存在するか」を先に見ると、原因の切り分けに役立ちます。

よくある誤り: 毎回のリクエストで flush する

「404 が直るから」と、テーマの functions.php やプラグインの init フックに flush_rewrite_rules() を書いてしまう例があります。これは避けるべき書き方です。

  • flush は、ルールを組み立ててデータベースへ書き込む処理を含む。アクセスのたびに走ると、不要な負荷になる。
  • ハードの場合は .htaccess への書き込みも発生しうる。
  • 動いているように見えても、問題の根本(登録のタイミング)が隠れてしまう。

正しい置き場所は、有効化フック(register_activation_hook)の中 です。そのとき、順序が重要になります。

function myplugin_register_types() {
    register_post_type( 'news', array(
        'public'  => true,
        'rewrite' => array( 'slug' => 'news' ),
    ) );
}
add_action( 'init', 'myplugin_register_types' );

function myplugin_activate() {
    // 先に登録してから flush する。順序が逆だと新ルールが含まれない
    myplugin_register_types();
    flush_rewrite_rules();
}
register_activation_hook( __FILE__, 'myplugin_activate' );

function myplugin_deactivate() {
    flush_rewrite_rules();
}
register_deactivation_hook( __FILE__, 'myplugin_deactivate' );

ポイントは、有効化の時点では init がまだ走っていない(このプラグインの登録が済んでいない)ため、flush の前に自分で登録関数を呼ぶ ことです。これを忘れると、flush しても新しいルールが含まれず、「有効化したのに 404」のままになります。

症状から原因を絞る順序

症状 まず疑うこと
新しい投稿タイプの個別ページだけ 404 rewrite rules が古い。wp rewrite list で該当ルールを確認
トップは表示されるが、投稿ページがすべて 404 .htaccess の欠落、またはサーバー側で書き換えが無効
ルールはあるのに 404 スラッグの競合(同名の固定ページなど)、またはプラグインの登録順
管理画面の保存で直るが、翌日また 404 何かが定期的に .htaccess やルールを上書きしている

最後の行は見落とされやすい点です。一時的に直って再発する場合は、flush を繰り返すより、何がルールや .htaccess を書き換えているのか を調べるほうが本筋です。

Nginx 環境での違い

Nginx は .htaccess を読みません。したがって「ハードflushで .htaccess を書き直す」という動きは意味を持たず、代わりにサーバー設定側に try_files などで index.php へ渡す記述が必要です。2段目(WordPress 本体のルール)は Apache でも Nginx でも同じ仕組みなので、1段目と2段目のどちらの問題かを切り分ける 考え方は共通です。

保守の場面での確認手順(例)

更新やメンテナンスの前後で、URL まわりを確認する手順の一例です。

  1. 作業前に、主要な URL(トップ、代表的な投稿、カスタム投稿タイプの一覧と個別ページ)を控えておく。
  2. 更新後、同じ URL を未ログインの状態で開き、表示を確認する。
  3. 404 があれば、まず wp rewrite list で期待するルールの有無を見る。
  4. ルールが欠けていれば wp rewrite flush を実行し、必要な場合のみ --hard を使う。
  5. 変更前のバックアップがあることを確認してから行う(考え方は3-2-1 ルールの記事を参照)。

flush 自体はデータの内容を変える操作ではありませんが、ハードの場合は .htaccess を書き換えるため、独自のルールを .htaccess に書き足している環境では事前に内容を控えておく と安心です。WordPress が管理するのは # BEGIN WordPress から # END WordPress の間だけで、その外側の記述は保持されます。

まとめ

  • rewrite rules は WordPress 本体の URL 解釈の対応表で、wp_options の rewrite_rules に保存される。登録を変えても自動では更新されない
  • 404 の原因が「1段目(サーバー)」か「2段目(WordPress のルール)」かを切り分けると、対処が絞れる
  • flush が要るのは、パーマリンク構造・投稿タイプ・タクソノミー・ルールを持つプラグインの変更時
  • flush_rewrite_rules() は毎回のリクエストで呼ばず、有効化フックの中で「登録してから」呼ぶ
  • 再発する 404 は、flush の繰り返しではなく、ルールや .htaccess を書き換えている原因を探す