WordPressのSEO対策で、意外と見落とされがちなのが canonical(カノニカル) の設定です。
canonicalはGoogleなどの検索エンジンに対して、
「このページの正規URLはこれです!」
と伝える重要なタグ。
正しく設定しておかないと…
- URLの重複(同じ内容のページが複数URLで存在)
- 検索順位が分散する
- 正しいページがインデックスされない
といったSEO上のトラブルにつながることがあります。
今回は、SEOプラグインを使わずに WordPressでcanonicalタグを自動生成して出力する方法を、実際のコード付きで解説します。
canonical(カノニカル)とは?なぜ必要?
canonical(正規URL)とは、ページのHTMLの <head> 内に入れる下記のようなタグです。
<link rel="canonical" href="https://example.com/page/">
このタグがあることで、検索エンジンは
このページの本体(正規URL)はこれ
パラメータ違い・URL違いのページは同一扱いにする
という判断ができます。
canonicalが必要になる典型例
URLが複数ある状態(重複コンテンツ)
WordPressでは、同じ内容が違うURLで見れてしまうケースがよくあります。
例
https://example.com/news/https://example.com/news/?utm_source=twitterhttps://example.com/news/?ref=xxx
内容は同じでもURLが違うと、検索エンジンは別ページとして扱う可能性があります。
canonicalはSEOプラグインでも設定できるが…
AIOSEO、Yoast、RankMathなどのSEOプラグインを使えば canonical は自動出力されます。
ただ、こんなケースもあります。
- プラグインを使っていないサイト
- カスタムテーマで自力SEOをやっている
- canonicalが二重出力されて崩れている
そんな時に役立つのが今回の方法です。
functions.phpでcanonicalを自動生成して出力する
以下のコードをテーマの functions.php に追加するだけで、ページ種別に応じた canonical を自動生成し、<head> に出力できます。
canonical自動生成コード(コピペOK)
<?php
/**
* Canonicalを自動出力(プラグイン無し想定)
* ※SEOプラグインを使っている場合は基本不要(むしろ二重になるので注意)
*/
// もし他でcanonicalが出てる/改変されてるなら一旦止める(必要な場合だけ)
remove_action('wp_head', 'rel_canonical');
// 自前でcanonicalを出す
add_action('wp_head', function () {
if (is_feed() || is_robots() || is_trackback()) return;
if (is_search()) return; // 検索結果ページは canonical を出さない派が多い(出すなら home_url('/?s=...') 等)
$canonical = '';
// singular(固定・投稿・カスタム投稿)
if (is_singular()) {
$canonical = get_permalink();
}
// カテゴリ/タグ/カスタムタクソノミー
elseif (is_category() || is_tag() || is_tax()) {
$canonical = get_term_link(get_queried_object());
}
// 投稿タイプアーカイブ
elseif (is_post_type_archive()) {
$canonical = get_post_type_archive_link(get_query_var('post_type'));
}
// 日付/著者アーカイブなど
elseif (is_author() || is_date()) {
$canonical = home_url(add_query_arg([], $GLOBALS['wp']->request));
$canonical = trailingslashit($canonical);
}
// トップ/フロント
elseif (is_front_page() || is_home()) {
$canonical = home_url('/');
}
// ページネーションは canonical に /page/2/ を付ける(※好みで1ページ目固定もあり)
if ($canonical && (is_paged() || get_query_var('paged'))) {
$paged = max(1, (int) get_query_var('paged'));
if ($paged > 1) {
$canonical = trailingslashit($canonical) . user_trailingslashit("page/{$paged}", 'paged');
}
}
if ($canonical && !is_wp_error($canonical)) {
echo '<link rel="canonical" href="' . esc_url($canonical) . '">' . "\n";
}
}, 1);
このコードの仕組みをわかりやすく解説
「なんとなくコピペしたけど…ちゃんと理解したい!」という方向けに、重要なポイントを噛み砕いて解説します。
① WordPress標準canonicalを止める
remove_action('wp_head', 'rel_canonical');
WordPressには、デフォルトでcanonicalを出す機能があります。
ただしテーマによって
- canonicalが出ない
- canonicalが変な形で出てる
- プラグインが上書きしてる
などが起こりやすいので、「一旦止めて自作で統一する」という方針になっています。
※SEOプラグインを使ってる場合はここが危険(canonical二重出力)なので注意!
② 出力しないページを除外
if (is_feed() || is_robots() || is_trackback()) return;
if (is_search()) return;
- RSS(feed)
- robots.txt
- trackback
- 検索結果ページ
こういったページにcanonicalを出す必要はない/出すと逆効果なことがあるので除外しています。
③ 投稿・固定ページなどは get_permalink()
if (is_singular()) {
$canonical = get_permalink();
}
投稿ページ/固定ページ/カスタム投稿タイプなどは
正規URL=パーマリンクなので get_permalink() でOKです。
④ カテゴリ/タグ/カスタムタクソノミー
elseif (is_category() || is_tag() || is_tax()) {
$canonical = get_term_link(get_queried_object());
}
カテゴリやタグの一覧ページなどは get_term_link() を使います。
⑤ 投稿タイプアーカイブにも対応
elseif (is_post_type_archive()) {
$canonical = get_post_type_archive_link(get_query_var('post_type'));
}
例えば items 投稿タイプの一覧ページ(アーカイブ)などもcanonicalを正しく出せます。
⑥ 著者・日付アーカイブ
elseif (is_author() || is_date()) {
$canonical = home_url(add_query_arg([], $GLOBALS['wp']->request));
$canonical = trailingslashit($canonical);
}
著者ページや日付アーカイブは URL生成が特殊なことがあるので、requestベースで作っています。
⑦ トップページにも対応
elseif (is_front_page() || is_home()) {
$canonical = home_url('/');
}
トップページは canonical を / に統一。これが正解です。
ページネーションのcanonical対応も抜かりなし!
一覧ページでよくあるのが
- 1ページ目:
/news/ - 2ページ目:
/news/page/2/
この時、canonicalを全部 /news/ にすると逆にSEO評価が崩れることがあります。
このコードはページネーションがある場合、
page/2 を canonical に反映page/3 も同様に反映
できるようになっています。
if ($canonical && (is_paged() || get_query_var('paged'))) {
$paged = max(1, (int) get_query_var('paged'));
if ($paged > 1) {
$canonical = trailingslashit($canonical) . user_trailingslashit("page/{$paged}", 'paged');
}
}
SEOプラグイン導入済みの場合は要注意(canonical二重問題)
ここ本当に大事です。
AIOSEO/Yoast/RankMath を入れている場合
→ ほぼ100% canonical が自動出力されています。
functions.php側でも canonical を出すと…
- canonicalが二重に出る
- 検索エンジンが混乱する
- SEO的に逆効果
という事故になりやすいです。
プラグインを使うなら、今回のコードは基本不要!
canonicalが正しく出ているか確認する方法
最後に確認手順です。
- canonicalを確認したいページを開く
- 右クリック →「ページのソースを表示」
canonicalで検索
正しく出ていれば:
<link rel="canonical" href="https://example.com/page/">
が <head> 内に表示されています。
まとめ|canonicalは「サイトのSEOを守る保険」
canonicalをちゃんと設定しておくと
重複コンテンツを防ぐ
インデックスが整理される
SEO評価が分散しにくい
というメリットがあります。
SEOプラグインを使っていない方や、テーマを完全自作している方には、今回のコードはかなり実用的です。

