結論
カスタムタクソノミーのアーカイブ(例: /genre/rock/)が404になる主な原因は次の3つです。
- リライトルールが更新されていない。登録直後は、保存済みのルールに新しい URL が入っていません。
register_taxonomy()をinitフックで呼んでいない。rewriteやpublic/publicly_queryableの設定が意図と違う。
最短の対処は、管理画面の「設定 → パーマリンク」で「変更を保存」を押すことです。コードで対応するなら、プラグインの有効化時に1回だけ flush_rewrite_rules() を呼びます。テーマの functions.php で毎回呼ぶのは避けます。
原因・仕組み
WordPress は、URL とクエリの対応表(リライトルール)を rewrite_rules オプションに保存し、リクエストのたびにそれを参照します。タクソノミーを登録すると、メモリ上の登録情報は増えますが、保存済みの対応表は自動では作り直されません。そのため、get_term_link() は /genre/rock/ というURLを返すのに、アクセスすると404になります。
公式リファレンスでも、登録後は「リライトルールのフラッシュが必要な場合がある」と書かれています。また、タクソノミー名は1〜32文字で、小文字英数字・ダッシュ・アンダースコアのみです。
手順(サンプルコード)
add_action( 'init', function () {
register_taxonomy( 'genre', 'post', array(
'label' => 'ジャンル',
'public' => true,
'hierarchical' => true,
'show_in_rest' => true,
'rewrite' => array( 'slug' => 'genre' ),
) );
} );
プラグインとして配布するなら、登録処理を関数にして、有効化時にも呼びます。
function my_register_genre() {
register_taxonomy( 'genre', 'post', array(
'public' => true, 'hierarchical' => true,
'rewrite' => array( 'slug' => 'genre' ),
) );
}
add_action( 'init', 'my_register_genre' );
register_activation_hook( __FILE__, function () {
my_register_genre(); // 先に登録してから
flush_rewrite_rules(); // ルールを作り直す
} );
テーマの場合は、管理画面で一度パーマリンクを保存します。ソース管理に含めたい場合は、delete_option( 'rewrite_rules' ) で保存済みルールを消して、WordPress に次回の適切なタイミングで再生成させる方法もあります。
動作確認(検証環境と結果)
WordPress 7.1.2(ja)/PHP 8.2.12/MariaDB 10.4.32、パーマリンクは /%postname%/。run.php から実行しました(tests フォルダの p3.php)。
link: http://localhost/genre/rock/
rule for genre/ present before flush: false
after flush: genre/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$ ...
- 登録直後は、保存済みの
rewrite_rulesにgenre/始まりのルールがありませんでした(false)。URL 自体はget_term_link()が生成できています。 flush_rewrite_rules( false )のあとには、genre/([^/]+)/...のルールが追加されました。- 33文字以上の名前では
taxonomy_length_invalidエラー(WP_Error)が返り、「タクソノミー名の長さは1から32文字でなければいけません」という通知が出ました。 - ブラウザでの実アクセス(HTTP 404 から 200 への変化)は、この CLI 環境では確認していません。
カスタムタクソノミー アーカイブが404になる原因と対処の注意点
flush_rewrite_rules()は処理が重く、公式リファレンスも「必要なときだけ呼ぶ」ことを求めています。initごとやフロント側での呼び出しは避けます。- 引数
$hardが true(既定)だと.htaccessも書き換えます。権限がない環境では失敗することがあります。 - 有効化フックの中では、先にタクソノミーを登録してからフラッシュします。順序が逆だと、新しいルールが入りません。
rewrite => falseにすると、きれいなURLそのものが作られません。- 同じスラッグの固定ページや投稿タイプがあると、競合して意図しない画面になります。
カスタムタクソノミー アーカイブが404になる原因と対処でよくあるミス
register_taxonomy()をinitより前(plugins_loaded など)や、条件付きで呼んでいる。- スラッグにスペースや大文字を使っている(
'rewrite' => array('slug' => 'My Genre'))。 - 投稿タイプ側を
public => falseにしていて、タームに属する投稿が1件も表示されない。 - ターム自体に投稿が1件も無く、テンプレートが空のページを返しているだけなのに、404と勘違いする。
- functions.php に
flush_rewrite_rules()を書いたまま本番に出し、サイトが重くなる。
カスタムタクソノミー アーカイブが404になる原因と対処のチェックリスト
- [ ]
initフックで登録している - [ ] 登録後に「設定 → パーマリンク」を保存した
- [ ]
rewriteのスラッグが意図通りで、他と競合していない - [ ]
public/publicly_queryableを確認した - [ ]
flush_rewrite_rules()が毎回実行されていない - [ ] ターム名が32文字以内
カスタムタクソノミー アーカイブが404になる原因と対処のFAQ(よくある質問)
Q. パーマリンクを保存しても直りません。
A. .htaccess が無い、mod_rewrite が無効、AllowOverride が None など、サーバー側の問題が考えられます。
Q. テンプレートは何が使われますか。
A. taxonomy-genre-rock.php、taxonomy-genre.php、taxonomy.php、archive.php の順に探されます。
Q. REST API で使うには。
A. show_in_rest を true にします。ブロックエディターでも必要です。
筆者の見解(カスタムタクソノミー アーカイブが404になる原因と対処)
タクソノミーの404は、コードのバグというより「ルールの再生成を忘れた」ことが原因のことが大半だと考えています。私見では、まずパーマリンク保存を試し、それで直るなら設定は正しい、と切り分けるのが近道です。恒久対応は有効化フックでの1回だけにとどめるのが安全です。
カスタムタクソノミー アーカイブが404になる原因と対処の関連項目
- register_taxonomy() の使い方|説明・引数・注意点
- flush_rewrite_rules() の使い方|説明・引数・注意点
- get_term_link() の使い方|説明・引数・注意点
- taxonomy_exists() の使い方|説明・引数・注意点
- add_rewrite_rule() の使い方|説明・引数・注意点
