WordPressでカスタム投稿タイプを作るとき、意外と悩むのが「カテゴリ一覧ページのURLをどうするか」です。
この記事では、次の構成を例に考えていきます。
- カスタム投稿タイプ:
works(制作実績) - カテゴリ:Web制作、システム開発、デザイン
まず、カテゴリ一覧ページを用意しない場合の基本的なURLは以下のようになります。
# 制作実績の一覧
/works/
# 制作実績の詳細
/works/{SLUG}/
ここまでは、WordPressでよく見かけるシンプルなURL構成です。
では、「Web制作」の実績だけを一覧で表示したい場合、そのカテゴリ一覧ページのURLはどう設計するのがよいでしょうか。
代表的なパターンとして、次の4つが考えられます。
-
/works/category/web/
→categoryを1階層設ける形式 -
/works/web/
→ カテゴリのスラッグを/works/直下に置く形式 -
/works/?category=web
→ クエリパラメータでカテゴリを指定する形式 -
/works/category-web/
→category-というプレフィックスを付ける形式
なお、ここで使用している category という文字列はあくまで一例です。パスに含める固定文字列やクエリパラメータ名はサイトの設計に応じて変更できますが、この記事では分かりやすさのため category に統一します。
先に結論からまとめると、私はそれぞれのURLパターンを次のように整理しています。
| URL | WPでの実装しやすさ | URLの簡潔さ | 衝突しにくさ | 複数条件検索 | 将来の拡張 |
|---|---|---|---|---|---|
/works/category/{CATEGORY}/ |
◎ | ○ | ◎ | △ | ◎ |
/works/{CATEGORY}/ |
○ | ◎ | △ | △ | △ |
/works/?category={CATEGORY} |
○ | △ | ◎ | ◎ | ◎ |
/works/category-{CATEGORY}/ |
○ | ○ | ○ | △ | △ |
URLを設計するときは、パンくずとの関係も考える必要があります。
URLが簡潔で、コンテンツの階層をそのまま表しているほど、パンくずの構造も把握しやすいです。
例えば、/works/web/というURLは、次のパンくずと自然に対応します。
ホーム > 制作実績 > Web制作
この評価は絶対的なものではなく、サイトの要件によって変わります。
特に重要なのは、「どのURLが正解か」ではなく、何を優先するのかです。
どのURLでも実装自体は可能ですが、選ぶURLによって注意すべきポイントは変わります。
本記事では、主に次の観点からそれぞれのURLパターンを比較していきたいと思います。
- WordPressでの実装しやすさ
- URLの分かりやすさ
- 他のURLとの衝突
- SEO・インデックス管理
- キャッシュ
- 将来的な検索・絞り込みへの拡張性
- 運用ルール
- URL変更時の影響
URLパターンを比較する前に、カスタム投稿タイプのアーカイブとカテゴリ一覧ページの違いだけ整理しておきます。
/works/ は、works に登録された投稿全体を表示するカスタム投稿タイプのアーカイブです。
一方で、
/works/category/web/
は、works_category の web というタームに属する投稿を表示するタクソノミーアーカイブです。
WordPress上ではこの2つは別のアーカイブとして扱われるため、カテゴリ一覧ページのURLはカスタム投稿タイプのアーカイブURLとは分けて考える必要があります。
この記事では、以下の構成を前提として比較していきます。
投稿タイプ:works
タクソノミー:works_category
ターム:web(Web制作)、design(デザイン)など
また、URL例に登場する {CATEGORY} には、基本的にタームのスラッグが入るものとします。
1. /works/category/{CATEGORY}/
例えば、
/works/category/web/
/works/category/system/
/works/category/design/
というURLです。
個人的には、特別な要件がないのであれば、この形式が一番無難だと考えています。
メリット
1. WordPress標準の仕組みで実装しやすい
最大のメリットは、WordPress標準の仕組みで実装しやすいことです。
register_taxonomy()のrewrite['slug']にworks/categoryを指定すると、基本となるURL構造を設定できます。
register_taxonomy(
'works_category',
'works',
[
'public' => true,
'show_in_rest' => true,
'rewrite' => [
'slug' => 'works/category',
'with_front' => false,
],
]
);
この設定により、次の形式でタクソノミーアーカイブURLが生成されます。
/works/category/web/
WordPress標準のrewrite機能を利用できるため、独自にadd_rewrite_rule()を追加する必要がなく、比較的シンプルに実装できます。
参考:WordPress Developer Resources「register_taxonomy()」
https://developer.wordpress.org/reference/functions/register_taxonomy/
2. カテゴリ用のURLだと分かりやすい
/works/category/web/
を見れば、
works
└ category
└ web
という構造が分かります。
category という固定セグメントがあるため、カテゴリ一覧であることも明確です。
将来的に、
/works/tag/wordpress/
/works/area/tokyo/
/works/search/
/works/ranking/
といったURLを追加するときにも、役割を分離しやすくなります。
3. 記事詳細ページと衝突しにくい
例えば記事詳細を、
/works/sample-project/
としていても、
/works/category/web/
とはURL構造が異なります。
そのため、
/works/{POST_SLUG}/
と、
/works/category/{CATEGORY}/
を比較的安全に共存させられます。
4. キャッシュ設計も比較的素直
パスそのものが違うため、
/works/category/web/
/works/category/design/
をそれぞれ別URLとして扱えます。
一般的なページキャッシュやCDNでも、パスは基本的なキャッシュキーになるため、クエリパラメータ方式と比べると設計を考える項目が少なくなります。
デメリット
一番分かりやすいデメリットは、URLが少し長くなることです。
/works/web/
と比較すると、
/works/category/web/
には category が1階層追加されます。
また、webを省いた/works/category/へアクセスされた場合の扱いも、仕様として決めておいた方がよいでしょう。
対応としては、次のような選択肢があります。
- 404にする
-
/works/にリダイレクトする - カテゴリそのものの一覧ページにする
などが考えられます。
2. /works/{CATEGORY}/
この形式では、
/works/web/
/works/system/
/works/design/
のようなURLになります。
4パターンの中では最もURLが短く、見た目もきれいです。
メリット
1. URLが短く直感的
余計な固定文字列がありません。
/works/web/
このURLは、
制作実績 → Web制作
という階層をそのまま表しているため、人間にとっても理解しやすい構造です。
2. WordPress標準のtaxonomy rewriteでもURL自体は作れる
実は、この形式だから必ず独自の add_rewrite_rule() が必要になるわけではありません。
register_taxonomy(
'works_category',
'works',
[
'public' => true,
'rewrite' => [
'slug' => 'works',
'with_front' => false,
],
]
);
とすれば、taxonomy側では、
/works/web/
というpermalink structureを作ることができます。
つまり、実装コードそのものは一見非常にシンプルです。
ただし、この形式を採用する場合は、記事詳細ページとの関係を含めて、URL構造をもう少し検討する必要があります。
デメリット
1. 記事詳細ページとURL形式が重なる
例えば、カスタム投稿タイプworksの詳細ページを次の形式にしたとします。
/works/sample-project/
URLの構造は次のとおりです。
/works/{POST_SLUG}/
一方、カテゴリ一覧ページを/works/直下に配置すると、次の形式になります。
/works/{CATEGORY}/
この2つは、どちらも/works/の直下に任意のスラッグが1つ入る構造です。
記事詳細
/works/{POST_SLUG}/
カテゴリ一覧
/works/{CATEGORY}/
そのため、例えば次のURLがリクエストされた場合、URLの形式だけでは記事詳細ページとカテゴリ一覧ページを区別できません。
/works/web/
このURLは、次のどちらにも当てはまります。
webというスラッグの記事詳細ページ
webというスラッグのカテゴリ一覧ページ
register_taxonomy()の設定自体は簡単でも、カテゴリ一覧ページとカスタム投稿タイプの詳細ページが同じ名前空間を使用するため、rewriteルールが競合します。
WordPressではrewriteルールの優先順位によって先に一致したルールが適用されるため、一方は表示できても、もう一方が404になったり、意図しないページとして処理されたりする可能性があります。
カテゴリと記事で同じスラッグを使用しない運用にしても、WordPressが両方を自動的に検索して適切なページを表示してくれるわけではありません。そのため、このURL構成を採用する場合は、rewriteルールの競合を解決する実装が必要です。
衝突を回避する方法の一例
記事詳細ページをカテゴリ配下に配置し、カテゴリ一覧ページとURLの階層を分ける方法があります。
一覧
/works/
カテゴリ一覧
/works/{CATEGORY}/
記事詳細
/works/{CATEGORY}/{POST_SLUG}/
例えば、次のような構成です。
カテゴリ一覧
/works/web/
記事詳細
/works/web/sample-project/
なお、この詳細URLを実現するには、カテゴリ一覧ページのrewrite設定だけでなく、カスタム投稿タイプ側でもカテゴリのスラッグを含むパーマリンク構造を設定し、投稿リンクの生成処理とrewriteルールを調整する必要があります。
カテゴリ一覧と記事詳細でURLの階層が異なるため、同じ階層を使用した場合に発生するrewriteルールの競合を回避できます。また、記事の所属カテゴリがURLから分かり、パンくずとも自然に対応します。
ホーム > 制作実績 > Web制作 > 記事タイトル
ただし、記事のカテゴリを変更すると、詳細ページのURLも変わります。
記事のカテゴリをwebからdesignへ変更した場合、URLは次のように変わります。
変更前:/works/web/sample-project/
変更後:/works/design/sample-project/
このように、記事詳細URLに使用しているカテゴリを変更した場合は、旧URLから新URLへの301リダイレクトが必要です。
また、1つの記事に複数のカテゴリを設定する場合は、URLに使用する代表カテゴリを決める必要があるなど、運用や実装が複雑になります。
1記事につき1カテゴリを設定する方針が決まっており、将来的にもカテゴリ構成を複雑にする予定がないサイトであれば、運用上の問題は起こりにくく、採用しやすい構成です。
URLの簡潔さと階層の分かりやすさを重視する場合は、選択肢のひとつとして検討してみてください。
3. /works/?category={CATEGORY}
/works/?category=web のように、クエリパラメータを使ってカテゴリを指定する方式です。
ここでひとつ注意したいのが、クエリパラメータの名前です。
WordPressでは cat は標準の「カテゴリー」を指定するためのクエリ変数として使われています。WP_Query でも、cat はカテゴリーIDを指定するパラメータとして定義されています。
参考:WordPress Developer Resources「WP_Query」
https://developer.wordpress.org/reference/classes/wp_query/
一方、works_category のようなカスタムタクソノミーでは、register_taxonomy() の query_var を使ってクエリ変数を設定できます。
次のように設定すると、
register_taxonomy(
'works_category',
'works',
[
'public' => true,
'query_var' => 'works_category',
'rewrite' => false,
]
);
/works/?works_category=web
のように、タームのスラッグをクエリパラメータとして指定できます。
query_var を特に指定しなかった場合は、基本的にタクソノミー名がクエリ変数として使用されます。また、任意の文字列を指定してクエリ変数の名前を変更することもできます。
参考:WordPress Developer Resources「register_taxonomy()」
https://developer.wordpress.org/reference/functions/register_taxonomy/
そのため、この記事で使用している、
/works/?category={CATEGORY}
は、あくまで「クエリパラメータ方式」を分かりやすく表したURL例です。
実際に実装する際は、WordPressですでに使用されているクエリ変数との衝突を避けながら、タクソノミーやサイトの設計に合わせてパラメータ名を決める必要があります。
メリット
1. 検索・絞り込み機能への拡張性が高い
この方式の大きなメリットは、検索条件を追加しやすいことです。
最初は、
/works/?category=web
だったとしても、将来的に、
/works/?category=web&area=tokyo
や、
/works/?category=web&year=2026&sort=new
のように、カテゴリ以外の条件も追加できます。
また、複数のカテゴリで絞り込みたい場合も、
/works/?category=web,wordpress
のようなルールを決めて、tax_query に変換できます。
[
'taxonomy' => 'works_category',
'field' => 'slug',
'terms' => [ 'web', 'wordpress' ],
'operator' => 'AND',
]
WP_Tax_Query は、複数のtermや AND、IN などの演算子(operator)をサポートしています。
参考:WordPress Developer Resources「WP_Tax_Query::__construct()」
https://developer.wordpress.org/reference/classes/wp_tax_query/__construct/
なお、1つの記事に複数カテゴリを設定すること自体は、今回紹介している他のURL形式でも問題ありません。
クエリパラメータ方式が特に強いのは、カテゴリだけでなく、エリアや年度、タグ、並び順など、複数の条件を組み合わせて検索・絞り込みを行いたい場合です。
検索・絞り込みUIを今後充実させる予定があるサイトでは、特に相性の良い方式といえます。
2. 検索条件が増えてもURL構造を変更しなくてよい
クエリパラメータ方式では、条件が増えても /works/ という一覧ページを基準にできます。
/works/?category=web
/works/?category=web&area=tokyo
/works/?category=web&area=tokyo&year=2026
このように、「一覧ページに検索条件を与える」という形で機能を追加できるため、条件が増えるたびにURL階層そのものを設計し直す必要がありません。
カテゴリ以外にもさまざまな絞り込み条件を追加する可能性がある場合には、拡張しやすい構成です。
デメリット
1. カテゴリ一覧ページとしてはURLが少し分かりづらい
/works/category/web/
と、
/works/?category=web
を比較すると、後者は「カテゴリ一覧ページ」というよりも、検索結果や絞り込み結果のURLに見えます。
カテゴリ一覧ページを独立したコンテンツとして分かりやすく見せたい場合は、パス形式の方が向いています。
2. 同じ内容を表すURLが増えやすい
複数のクエリパラメータを扱うようになると、
/works/?category=web&area=tokyo
/works/?area=tokyo&category=web
のように、パラメータの並び順が異なるURLを生成できてしまいます。
また、
/works/?category=web
/works/?category=web&sort=default
のように、実質的には同じ内容を表示するURLが複数存在する可能性もあります。
そのため、canonicalやインデックス方針、URLを生成するときのルールなどをあらかじめ決めておく必要があります。
3. キャッシュの扱いを確認する必要がある
クエリパラメータ付きURLだからキャッシュできない、というわけではありません。
ただし、CDNやキャッシュ機能の設定によって、?以降の条件を別ページとして区別する場合と、同じページとして扱う場合があります。
例えば、次の2つは異なるカテゴリを表示するURLです。
/works/?category=web
/works/?category=design
をそれぞれ別のページとしてキャッシュする場合は、category の値を区別してキャッシュする必要があります。
環境によっては、
- すべてのクエリ文字列をキャッシュキーに含める
- 特定のパラメータだけを含める
- クエリ文字列を無視する
- パラメータを正規化する
といった違いがあります。
そのため、パス形式と比べると、利用しているキャッシュ環境の仕様を確認する場面が増えます。
4. パラメータの運用ルールが必要になる
クエリパラメータは追加しやすい反面、ルールを決めていないと、
category
cat
category_id
term
type
のように、似た役割のパラメータが増えてしまう可能性があります。
クエリパラメータ方式を採用するのであれば、
カテゴリ:category
エリア:area
並び順:sort
のように、サイト全体で命名ルールを決めておくと管理しやすくなります。
クエリパラメータ方式は、検索・絞り込み機能への拡張性が高い一方で、canonicalやキャッシュ、パラメータ名など、URLを運用するためのルールは他の方式より少し増えやすい点に注意が必要です。
4. /works/category-{CATEGORY}/
/works/category-web/
/works/category-system/
/works/category-design/
という形式です。
固定のディレクトリを1階層作るのではなく、category- というプレフィックスを使ってURLの種類を判別します。
メリット
1. /works/ 直下を維持しながらカテゴリだと判別できる
/works/web/
ではカテゴリなのか記事なのか曖昧でした。
一方、
/works/category-web/
なら category- が付いているため、カテゴリURLだと判断できます。
2. 通常の記事URLとの衝突を抑えられる
/works/sample-project/
と、
/works/category-web/
ならURLパターンを分けることができます。
ただし、
category-
から始まる記事のスラッグを許可すると再び競合するため、
category-はカテゴリ用のプレフィックスとする
という運用ルールは必要です。
3. パスベースのURLとして扱える
クエリパラメータではないため、
/works/category-web/
そのものを1つのURLとして扱えます。
一般的なページキャッシュでも通常のパスとして扱いやすい構造です。
デメリット
1. タームのスラッグ設計によって実装方法が変わる
ここは重要です。
WordPress標準のタクソノミー rewriteは基本的に、
{rewrite slug}/{term slug}/
という構造です。
'rewrite' => [
'slug' => 'works/category',
]
なら、
/works/category/web/
になります。
一方で、
/works/category-web/
は、
category-
という固定文字列と、
web
というterm slugを同一のパスセグメント内で連結しています。
そのため、web のようなタームのスラッグをそのまま使い、URL上でのみ category- を付与したい場合は、通常の rewrite['slug'] だけでは表現しづらく、独自rewriteが必要になりやすい形式です。
なお、URLとして /works/category-web/ という形を実現するだけであれば、タームのスラッグ自体を、
category-web
category-system
category-design
のように統一する方法もあります。
この場合は、厳密には category- をURL生成時に付与しているのではなく、タームのスラッグそのものに含めています。タクソノミー側のリライトスラッグを works とすることで、WordPress標準のrewrite機能でも、
/works/category-web/
という形のURL自体は生成できます。
ただし、記事詳細URLも /works/{POST_SLUG}/ としている場合は、タクソノミーとカスタム投稿タイプの詳細ページがどちらも /works/{任意のslug}/ というrewrite構造を使うことになります。そのため、タームのスラッグに category- を付けるだけでrewriteの競合まで解消できるわけではありません。
category- をURL上の明確な判別条件として使い、記事詳細URLと確実に振り分けたい場合は、後述するように独自rewriteを設計する方法があります。
WordPressのタクソノミー rewriteでは、設定したリライトスラッグとタクソノミーのrewrite tagをもとにpermalink structureが登録されます。
参考:WordPress Developer Resources「WP_Taxonomy::add_rewrite_rules()」
https://developer.wordpress.org/reference/classes/wp_taxonomy/add_rewrite_rules/
一方、タームのスラッグには web を使いながら、URLだけを /works/category-web/ としたい場合は、例えば次のような独自rewriteを実装します。
add_action( 'init', function () {
add_rewrite_rule(
'^works/category-([^/]+)/page/([0-9]+)/?$',
'index.php?works_category=$matches[1]&paged=$matches[2]',
'top'
);
add_rewrite_rule(
'^works/category-([^/]+)/?$',
'index.php?works_category=$matches[1]',
'top'
);
} );
のような独自ルールを作ることになります。
termリンク側も、
add_filter(
'term_link',
function ( $url, $term, $taxonomy ) {
if ( 'works_category' !== $taxonomy ) {
return $url;
}
return home_url(
user_trailingslashit(
'works/category-' . $term->slug
)
);
},
10,
3
);
などの調整が必要になります。
実際の案件では階層タクソノミー、feed、ページネーションなどの要件も考慮する必要があります。
つまり、
URL構造はシンプルに見えるが、WordPress実装は
/works/category/{CATEGORY}/より複雑
という点には注意が必要です。
2. 独自の命名ルールを長期間維持する必要がある
将来的に、
/works/category-web/
/works/tag-wordpress/
/works/area-tokyo/
/works/year-2026/
のようなルールが増えてくる可能性があります。
ディレクトリ構造ではなく文字列プレフィックスで種類を表現するため、独自ルールが増えるほど管理が複雑になります。
3. 積極的に採用する理由は比較的少ない
/works/category/web/
ならWordPress標準のtaxonomy rewriteに乗せられます。
/works/web/
ならURLを最も短くできます。
/works/?category=web
なら検索条件として高い拡張性があります。
それらと比較すると、
/works/category-web/
は、
/works/直下に置きたいが、カテゴリであることも明示したい
という要件がある場合の中間案という位置付けになります。
ページネーションはURL選定の大きな判断材料になるのか?
今回の4パターンについては、
このURLを採用するとページネーションが扱いにくくなる
というものは基本的にありません。
/works/category/web/page/2/
や、
/works/web/page/2/
といったURLも、適切にrewriteを設定すれば実現できます。
WordPressには、permalink structureから /page/2/ のようなアーカイブ用のページネーションルールを生成する仕組みがあります。
WP_Rewrite::generate_rewrite_rules() でも、$paged はデフォルトで true に設定されています。
参考:WordPress Developer Resources「WP_Rewrite::generate_rewrite_rules()」
https://developer.wordpress.org/reference/classes/wp_rewrite/generate_rewrite_rules/
クエリパラメータ方式であれば、
/works/?works_category=web&paged=2
のようにページ番号を指定できます。
一方で注意したいのは、
/works/category-{CATEGORY}/
のように、add_rewrite_rule() などを使って独自のURL構造を実装する場合です。
この場合は、
/works/category-web/page/2/
のようなページネーションURLについても、独自のrewriteルールで正しく処理できるようにしておく必要があります。
つまり、ページネーション自体を理由にURLを選ぶというよりも、WordPress標準のrewriteの仕組みに乗せられるか、それとも独自rewriteまで自分で管理する必要があるかを確認する方が重要です。
カテゴリのスラッグを変更したときはどうなる?
今回の4パターンでは、基本的に {CATEGORY} にslugを使っています。
したがって、
web
を、
web-production
へ変更すれば、
/works/category/web/
から、
/works/category/web-production/
へURLも変わります。
これは、
/works/web/
/works/?category=web
/works/category-web/
でも基本的には同じです。
カテゴリのスラッグを変更する可能性がある場合は、
- slugは公開後なるべく変更しない
- 変更する場合は旧URLから301リダイレクトする
といった運用もあわせて考えておく必要があります。
カテゴリ名の表示文言を変更することと、カテゴリのスラッグを変更することは分けて考えた方が安全です。
「カテゴリは使うけれどカテゴリ一覧ページは公開しない」場合
実案件では、管理画面上ではカテゴリを使いたいものの、カテゴリ一覧ページ自体は必要ないケースもあります。
制作実績を「Web制作」「システム開発」「デザイン」で分類したいが、
/works/category/web/のようなカテゴリ一覧ページは公開しない
といった仕様です。
ここで注意したいのが、タクソノミー用のテンプレートを作らなければ、カテゴリ一覧ページも存在しなくなるわけではないという点です。
PHPテンプレートを使うクラシックテーマでは、例えば taxonomy-works_category.php が存在しなくても、使用できるテンプレートを次のような順番で探します。
taxonomy-{taxonomy}-{term}.php
↓
taxonomy-{taxonomy}.php
↓
taxonomy.php
↓
archive.php
↓
index.php
そのため、専用テンプレートを作っていなくても、archive.php や index.php が使用され、タクソノミーアーカイブが表示される可能性があります。
参考:WordPress Developer Resources「Template Hierarchy」
https://developer.wordpress.org/themes/classic-themes/basics/template-hierarchy/
そのため、カテゴリ一覧ページそのものが不要なのであれば、テンプレートを作らないだけではなく、register_taxonomy() の段階で「このタクソノミーはフロントでは公開しない」と設定しておくと安心です。
register_taxonomy(
'works_category',
'works',
[
'hierarchical' => true,
// タクソノミーアーカイブとして公開しない
'public' => false,
'publicly_queryable' => false,
// 管理画面では使用する
'show_ui' => true,
'show_admin_column' => true,
// ブロックエディターから使用する場合
'show_in_rest' => true,
// タクソノミーアーカイブ用のURLを生成しない
'rewrite' => false,
// ?works_category=web のような問い合わせも使用しない
'query_var' => false,
]
);
public => false にすると show_ui もデフォルトでは無効になるため、管理画面ではカテゴリを使いたい場合は show_ui => true を明示します。
また、カテゴリ一覧ページを公開しないのであれば、当然XML Sitemapにも掲載する必要はありません。
WordPress CoreのXML Sitemapでは、公開対象となるタクソノミーがサイトマップに含まれるため、上記のようにタクソノミー自体をフロント側へ公開しない設計にしておけば、不要なタクソノミーアーカイブやサイトマップへの掲載も防ぎやすくなります。
参考:WordPress Developer Resources「WP_Sitemaps_Taxonomies::get_object_subtypes()」
https://developer.wordpress.org/reference/classes/wp_sitemaps_taxonomies/get_object_subtypes/
rewrite設定を変更したときの注意
register_taxonomy() の rewrite を変更したり、add_rewrite_rule() で独自のリライトルールを追加した場合は、WordPressのrewrite rulesを再生成する必要があります。
開発中であれば、管理画面の「設定 → パーマリンク」を開き、そのまま「変更を保存」をクリックすることでrewrite rulesを再生成できます。
参考:WordPress Developer Resources「add_rewrite_rule()」
https://developer.wordpress.org/reference/functions/add_rewrite_rule/
プラグインとして実装する場合などは、必要なタイミングで次の関数を実行します。
flush_rewrite_rules();
flush_rewrite_rules() は、現在保存されているrewrite rulesを削除し、新しいルールを再生成するための関数です。
参考:WordPress Developer Resources「flush_rewrite_rules()」
https://developer.wordpress.org/reference/functions/flush_rewrite_rules/
ただし、rewrite rulesの再生成は負荷の高い処理のため、
add_action( 'init', function () {
flush_rewrite_rules();
} );
のように、毎回のリクエストで実行するのは避けましょう。
WordPress公式ドキュメントでも、rewrite rulesのflushは負荷の高い処理であるため、必要なタイミングに限定して実行することが推奨されています。
参考:WordPress Developer Resources「WP_Rewrite::flush_rules()」
https://developer.wordpress.org/reference/classes/wp_rewrite/flush_rules/
結局どのURLを選ぶべきか
ここまで4つのURLパターンを見てきました。
これまで確認してきた実装方法やURLの衝突、拡張性、運用面などを踏まえると、特別な要件がなければ、私は次の順番で検討します。
1. /works/category/{CATEGORY}/
2. /works/{CATEGORY}/
3. /works/?category={CATEGORY}
4. /works/category-{CATEGORY}/
第一候補は /works/category/{CATEGORY}/ です。
URLは少し長くなりますが、WordPress標準のタクソノミーの仕組みで実装しやすく、記事詳細ページとのURLも分けやすいため、設計・実装・運用のバランスが取りやすい方式です。
将来的に、
/works/tag/{TAG}/
/works/area/{AREA}/
といった別の分類や機能を追加するときにも、URLの役割を分けやすくなります。
次に、/works/{CATEGORY}/です。
URLが短くシンプルなため、カスタム投稿タイプの配下に新たな機能を追加する可能性が低く、カテゴリ一覧としてシンプルに運用する場合に採用しやすい形式です。
/works/web/
/works/design/
のように見た目も分かりやすく、記事詳細ページもカテゴリ配下にまとめるのであれば、
/works/web/{SLUG}/
/works/design/{SLUG}/
のように、URL上でも「どのカテゴリの記事なのか」を表現できます。
一方で、記事詳細ページを /works/{POST_SLUG}/ とする場合は、カテゴリ一覧と同じURL階層を使うため競合に注意が必要です。
また、
/works/search/
/works/ranking/
/works/new/
などを将来的に追加する場合も、カテゴリのスラッグとぶつからないよう運用ルールを考える必要があります。
なお、記事詳細URLにもカテゴリを含める場合は、前述したカテゴリ変更時のURLへの影響や、複数カテゴリを設定した場合の運用にも注意が必要です。
3番目は /works/?category={CATEGORY} です。
単純なカテゴリ一覧ページとして考えると優先度は下がりますが、検索や絞り込み機能が中心となるサイトでは評価が大きく変わります。
/works/?category=web&area=tokyo&year=2026
のように条件を追加しやすいため、カテゴリ以外にもエリア、年度、タグ、並び順など、複数の条件を扱うのであれば有力な選択肢です。
その代わり、canonicalやインデックス、キャッシュキー、クエリパラメータの命名など、運用上考えることも増えてきます。
最後は/works/category-{CATEGORY}/です。
/works/直下に配置しながら、category-というプレフィックスによってカテゴリURLだと判別できる点がメリットです。
タームのスラッグ自体を category-web のように統一すれば、WordPress標準のrewrite機能でも同じ形のURL自体は生成できます。ただし、記事詳細も /works/{POST_SLUG}/ とする場合はrewrite構造が重なるため、競合には別途注意が必要です。
そのため、URLの見た目だけでなく、category- をタームのスラッグの命名ルールとして持たせるのか、URL生成時に付与するのかまで含めて検討した方がよいでしょう。
もちろん、この順位が絶対というわけではありません。
検索・絞り込み機能が中心であれば /works/?category={CATEGORY} の優先度は上がりますし、URLの短さを最優先するのであれば /works/{CATEGORY}/ が第一候補になることもあります。
また、そもそもカテゴリを管理上の分類として使うだけで、カテゴリ一覧ページを公開しないのであれば、URLをどうするかではなく、publicly_queryable や rewrite、query_var などを使ってタクソノミーをフロント側に公開しない設計を検討することになります。
カテゴリ一覧ページのURLは、一度公開すると簡単には変えづらくなります。
後から変更すれば、リダイレクトや検索エンジン、外部リンク、キャッシュなどにも影響します。
そのため、単純に「見た目がきれいだから」で決めるのではなく、記事詳細ページとの競合、将来の機能追加、検索・絞り込みの要件、WordPressでの実装方法や運用まで含めて、サイトが今後どう拡張されるかを考えながらURLルールを決めることが大切です。