【WordPress】カスタム投稿の導入後に通常投稿が表示されない原因と解決法

マックブックを覗きこむサラリーマン

WordPressにカスタム投稿タイプを追加したとたん、それまで普通に見えていた通常の投稿ページが真っ白になったり、404エラーで表示されなくなったり。「さっきまで動いていたのに」と頭を抱えた経験はないでしょうか。

私自身、長いWeb制作歴のなかで何度かこのワナにハマっています。あるサイトでregister_post_typeを仕込んだ翌日、固定ページは普通に開くのに通常投稿だけが軒並み404。single.phpの書き忘れという初歩ミスを疑ったものの、テンプレートはちゃんと作ってある。原因は思いがけないところにありました。

この記事では、カスタム投稿タイプを導入した直後に通常の投稿やアーカイブが表示されなくなる現象について、パーマリンクの再保存・スラッグの競合・テンプレート階層・pre_get_postsの副作用という5つの定番原因を、WordPress公式ドキュメントの裏付けつきで上から順にチェックできるようにまとめました。

カスタム投稿まわりの「表示されない」は、ほとんどがこのどれかに当てはまります。やっかいなのは、固定ページだけは普通に開けることが多く、一見すると原因の見当がつきにくい点です。だからこそ、当てずっぽうで触るのではなく、原因の多い順・対処のラクな順に上から潰していくのが結局いちばんの近道になります。

一番多くて一番カンタンな対処から順番に試していけば、たいていは数分で復活します。あわてて子テーマを作り直したり、プラグインを総入れ替えしたりする前に、まずはこの5項目を上から潰していきましょう。なお解説に出てくる挙動は、すべてWordPress公式ドキュメントで裏取りしたうえで2026年時点の情報として書いています。

まず試すべきはパーマリンクの再保存(リライトルールの再生成)

カスタム投稿を追加した直後の「表示されない」で、最初に疑うべきはこれです。WordPressはURLの振り分けルール(リライトルール)をデータベースにキャッシュしているため、新しい投稿タイプを登録しただけでは古いルールが残ったままになり、URLの解釈がズレて404が出ます。

解決はあっけないほど簡単で、管理画面の「設定」→「パーマリンク設定」を開き、何も変更せずに「変更を保存」ボタンを押すだけ。これでリライトルールが作り直され、カスタム投稿も通常投稿も正しいURLに振り分けられるようになります。

仕組みとしては、内部でflush_rewrite_rules()という処理が走ってルールが再生成されています。コードから明示的に流すこともできます。

register_activation_hook( __FILE__, function() {
    // ここでカスタム投稿タイプを登録してから
    my_register_post_types();
    flush_rewrite_rules();
});

ただしflush_rewrite_rules()は重い処理です。WordPress公式も「コストの高い処理なので毎回呼ぶべきではなく、プラグインの有効化時など必要なときだけ実行する」と明記しています。initフックや毎回のページ読み込みで呼ぶのは厳禁で、テンプレート内に書きっぱなしにすると表示速度を確実に落とします。

開発中や登録方法を変えた直後は、コードに書くより「パーマリンク設定を開いて保存」で手動フラッシュするのが手軽で安全です。私もまずこの一手から試します。これだけで直るケースが体感で一番多いです。

出典:flush_rewrite_rules() – WordPress Developer Resources

関連記事:WordPressカスタム投稿タイプが表示されない原因と解決方法【404エラー対処】

has_archiveとrewrite slugの設定を見直す

パーマリンクを再保存しても直らないときは、register_post_typeに渡している引数そのものを疑います。とくにhas_archiverewriteのスラッグ設定は、URLの形を直接決める部分なので、ここがズレると意図した一覧ページや個別ページが出てきません。

has_archivetrueにするとカスタム投稿のアーカイブ(一覧)ページが有効になり、URLのスラッグには投稿タイプ名がそのまま使われます。文字列を渡せばアーカイブ用のスラッグを別名にできます。rewriteは個別ページのパーマリンクを制御し、配列でslugを指定すればURLの一部を任意の文字列に変えられます。

register_post_type( 'works', array(
    'public'      => true,
    'has_archive' => true,                 // /works/ にアーカイブを作る
    'rewrite'     => array( 'slug' => 'works' ),
    'supports'    => array( 'title', 'editor', 'thumbnail' ),
) );

ここで注意したいのが、引数を変えたら必ずパーマリンクの再保存(前章のフラッシュ)が必要になる点です。has_archiveを後からtrueにしても、リライトルールを作り直さない限りアーカイブは404のままです。「設定を直したのに変わらない」と感じたら、たいていフラッシュ忘れです。

出典:register_post_type() – WordPress Developer Resources

スラッグが固定ページ・カテゴリーと重複していないか確認する

これが、冒頭で書いた私の失敗の正体です。カスタム投稿のrewriteスラッグと、既存のカテゴリースラッグや固定ページのスラッグがバッティングすると、同じURLの取り合いになり、通常投稿側が表示されなくなることがあります。

私のケースでは、カスタム投稿のスラッグに、すでに使っていたカテゴリーと同じ文字列を割り当ててしまっていました。URLの先頭部分が衝突して、WordPressがどちらを表示すべきか判断できず、結果として通常投稿のページが軒並み開けなくなったのです。固定ページは別の仕組みで解決されるため普通に表示され、それがかえって原因の切り分けを難しくしました。

チェックすべきポイントは次のとおりです。

// NG例:カテゴリースラッグ 'news' が既にあるのに同じ 'news' を使う
register_post_type( 'info', array(
    'rewrite' => array( 'slug' => 'news' ), // ← カテゴリーや固定ページと衝突
) );

// OK例:他で使っていない固有のスラッグにする
register_post_type( 'info', array(
    'rewrite' => array( 'slug' => 'company-news' ),
) );

確認の手順はシンプルで、カスタム投稿のスラッグが「カテゴリースラッグ」「タグスラッグ」「固定ページのスラッグ」「他のカスタム投稿・タクソノミーのスラッグ」のどれとも被っていないかを一つずつ照合するだけです。被っていたら、カスタム投稿側を他で使っていない固有の名前に変え、忘れずにパーマリンクを再保存します。スラッグは「サイト全体で取り合いになる名前空間」だと意識しておくと、この種のトラブルを未然に防げます。

pre_get_postsでメインクエリをいじったときの副作用

「アーカイブにカスタム投稿も一緒に表示したい」といった調整でpre_get_postsを使うと、書き方次第で通常投稿の表示や管理画面が巻き込まれて壊れることがあります。pre_get_postsはサイト内のほぼすべてのクエリで発火するため、条件分岐なしでpost_typeを書き換えると、サイドバーやフッターの副ループ、さらには管理画面の一覧にまで影響が及びます。

WordPress公式も、メインクエリだけを対象にするためにis_main_query()でチェックし、管理画面を巻き込まないようis_admin()を併用するよう促しています。最低限、次の形を守ってください。

add_action( 'pre_get_posts', function( $query ) {
    // 管理画面とサブクエリは触らない
    if ( is_admin() || ! $query->is_main_query() ) {
        return;
    }
    if ( $query->is_home() ) {
        // 通常投稿に加えてカスタム投稿も一覧に含める
        $query->set( 'post_type', array( 'post', 'works' ) );
    }
} );

ここでpost_typearray( 'works' )のように書いてしまうと、通常投稿(post)が一覧から丸ごと抜け落ちます。「投稿が消えた」と感じるトラブルの一因がこれです。複数を表示したいなら、必ずpostも配列に含めるのを忘れないでください。条件分岐のis_admin()is_main_query()の二重チェックは、副作用を防ぐ命綱だと考えてください。

出典:pre_get_posts – WordPress Developer Resources

テンプレート階層(single.php・archive.php)の取り違え

コードもスラッグも問題ないのに表示が崩れる場合は、テンプレートファイルの当たり方を疑います。WordPressは決まった優先順位(テンプレート階層)でファイルを探すため、カスタム投稿専用テンプレートと通常投稿用テンプレートの役割を取り違えると、意図しないファイルが使われて表示がおかしくなります。

個別ページはsingle-{投稿タイプ}.phpsingle.phpsingular.phpindex.phpの順に探されます。アーカイブはarchive-{投稿タイプ}.phparchive.phpindex.phpの順です。つまり、カスタム投稿用にsingle-works.phpを用意すればその投稿タイプだけ専用テンプレートが当たり、無ければ自動的にsingle.phpへフォールバックします。

ありがちなのが、カスタム投稿の見た目を整えるつもりでsingle.phpそのものを書き換えてしまい、通常投稿の表示まで巻き添えにするパターンです。通常投稿と分けたいなら、カスタム投稿側はsingle-{投稿タイプ}.phparchive-{投稿タイプ}.phpという専用ファイルを作るのが鉄則です。最終的にどのテンプレートにも当たらなければindex.phpが使われるので、真っ白ではなく「素っ気ない表示」になったときは、想定外のフォールバックが起きていないかを確認しましょう。

出典:Template Hierarchy – WordPress Developer Resources

まとめ:上から順に潰せば、たいてい数分で直る

カスタム投稿を入れたら通常投稿が消えた——というトラブルは、見た目のインパクトのわりに原因はだいたい決まっています。やみくもに触る前に、原因の多い順・対処のラクな順で上から潰していくのが一番の近道です。

あらためて確認の順番をおさらいします。まずは「設定」→「パーマリンク設定」で何も変えずに保存し、リライトルールを再生成すること。これだけで直るケースが体感で最多です。次にregister_post_typehas_archiverewriteスラッグの設定を見直し、引数を変えたら必ずパーマリンクを再保存します。

それでもダメなら、カスタム投稿のスラッグが固定ページ・カテゴリー・タグなどと競合していないかを照合します。私が実際にハマったのもこの競合で、スラッグは「サイト全体で取り合う名前」だと意識するだけで防げます。pre_get_postsを使っているならis_admin()is_main_query()のチェックと、postを配列に含め忘れていないかを確認。最後にテンプレート階層を見直し、通常投稿とカスタム投稿のテンプレートを取り違えていないかをチェックします。

この5項目を上から順にチェックすれば、カスタム投稿まわりの「表示されない」のほとんどは数分で解決できます。新しい投稿タイプを足したあとに何かおかしいと感じたら、まずはパーマリンクの再保存。これを合言葉にしておけば、同じワナで時間を溶かすことはぐっと減るはずです。