続き物ページを表す「rel=”next” rel=”prev”」タグをWordPressで最適化して利用するカスタマイズ方法

わかったブログさんにSimplicityのSEOのご提案として以下の記事を書いていただきました。

ttp://www.wakatta-blog.com/simplicity-seo-wakatta-blog.html (現在は公開停止)

いろいろ参考になる記事です。

中でも、僕は「rel=”next” rel=”prev”」タグの有効的な使い方については、ほとんど知りませんでした。なので僕も改めて自分で調べてみて、Wordpressでの最適な使い方を考えてみました。

今回は、その「rel=”next” rel=”prev”」タグを付加するWordpressカスタマイズ方法の紹介です。

スポンサーリンク
レクタングル(大)広告

そもそも「rel=”next” rel=”prev”」タグとは

Googleによると「rel=”next” rel=”prev”」タグは、本来、続き物になっているページの関連性を示すために使うそうです。

WordPressで言えば、「投稿・固定ページの1つのページを<!–nextpage–>タグなどを利用して、複数に分けている分割ページ」などが当てはまると思います。

例えば、Simplicityページでは、以下のページがそれにあたります。

SimplicityでHTML要素を用いて記事を書くと、以下のようなレイアウトになります。 Wordpressテストデータを用いたデモサイトはこちら。 見出し弐 吾輩は猫である。名前はまだ無い。どこで生れたかとんと見当がつかぬ。何でも薄

このページの下の方には、以下のようにページリンクが表示されており、「1つの記事を4つに分けた続きものの分割ページ」ということがわかると思います。

ページ分割リンク

「rel=”next” rel=”prev”」タグは、こういった「続き物のコンテンツのURL間の構成」を検索エンジンに知らせる役割を果たします。

このタグを指定することにより、以下のようなSEO的な効果があると考えられます。

  • リンクがばらばらの状態ではなく一連のグループとして取り扱われる
  • 最も関連性が高いページ(通常は最初のページ)にユーザーを誘導する

これにより、続きものになっているコンテンツの個々のURL間の関係性をGoogleに示すことができます。

続き物コンテンツの例

Google Consoleヘルプウェブマスター向け公式ブログでは、こういった続き物コンテンツの例として以下のように書かれています。

  • ニュースや出版サイト等の 1 つの記事を複数のページに分けているもの
  • 小売サイトであれば、商品をカテゴリに分類して複数のページに分けてあるもの
  • 同一の製品カテゴリに属する製品を複数ページにまたがって掲載しているもの
  • フォーラムの 1 つのスレッドを一連の複数 URL に分割しているもの

こういったページに適切にnext/prevタグを利用すると効果的なようです。

WordPressでのnext/prevタグの利用

WordPressで「rel=”next” rel=”prev”」タグを利用すべき時と言えば、やっぱり、「1つのページを複数に分けた分割ページ(マルチページ)」に適用するのが推奨されるかと思います。

デフォルト設定状態のWordpress動作

ただデフォルトのWordpressの設定では、投稿ページに対して「前の記事」「次の記事」といった感じで、「rel=”next” rel=”prev”」タグが利用されているようです。

WordPressで、小説を書いているのならば、投稿ページそれぞれが続きもののコンテンツとも言えないことはありません。

ただ、通常ブログを書いている人の多くは、「1つの投稿に対して1つの内容」を書いている場合も多く、続き物として書いている人の方が少ないと思います。

なので、デフォルトで投稿ページ1つ1つに「rel=”next” rel=”prev”」タグを割り振る動作は停止させる必要があるのではないかと思います。

トップページやカテゴリページでのページネーション

あと、パズ部さんの記事に以下のようにも書かれています。

続きもののコンテンツ以外にも、例えば、CMSで自動生成されるカテゴリーページも通常、ページネーションが設定されている。その場合、最初のカテゴリーページだけがインデックスされるように rel=”next” や rel=”prev” を設定するとインデックス最適化を行うことができる。

これを参考に、トップの記事一覧や、カテゴリー一覧などでページネーションが使われているページにも「rel=”next” rel=”prev”」タグを利用したいと思います。

All in One SEO Packを見ても、一覧のページネーション分割でも利用されているようなので。


以下記事は、続き物コンテンツへの設定方法から、設定に関する注意点まで、かなりわかりやすく書いてあるので、タグの設定をする際には、一読しておくことをおすすめします。

様々なサイトを見ていると、数あるタグの中で意外と間違って設定されているのが、このrel="next"とrel="prev"タグだ。このタグを間違えて使ってしまうと、検索エンジンがサイトの構成を誤解してしまう可能性が少なからずある。そうなると

WordPressカスタマイズのポイント

これまでのことを踏まえ、今から行うWordpressカスタマイズでは、以下の3つのポイントカスタマイズしたいと思います。

  1. デフォルト機能で投稿ページごとにnext/prevタグを割り振られている場合は停止させる
  2. 1ページを複数に分けた分割ページにnext/prevタグを追加する
  3. 「投稿一覧」や「カテゴリ一覧」のようなページネーション分割ページにnext/prevタグを追加する

今回は、functions.phpにコピペするのみで、これらの動作を実現したいと思います。

functions.phpのカスタマイズ

上に書いた3つのカスタマイズを、まとめてfunctions.phpに記述します。(子テーマをカスタマイズする場合は、子テーマのfunctions.phpに記述する)。

functions.phpに記述するコード全部は以下になります。

///////////////////////////////////////
// WordPressデフォルトのnext/prev出力動作を停止
///////////////////////////////////////
remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');

///////////////////////////////////////
//ページネーション(一覧ページ)と分割ページ(マルチページ)タグを出力
///////////////////////////////////////
function rel_next_prev_link_tags() {
  if(is_single() || is_page()) {
      //1ページを複数に分けた分割ページ(マルチページ)でのタグ出力
    global $wp_query;
    $multipage = check_multi_page();
    if($multipage[0] > 1) {
      $prev = generate_multipage_url('prev');
      $next = generate_multipage_url('next');
      if($prev) {
        echo '<link rel="prev" href="'.$prev.'" />'.PHP_EOL;
      }
      if($next) {
        echo '<link rel="next" href="'.$next.'" />'.PHP_EOL;
      }
    }
  } else{
    //トップページやカテゴリページなどのページネーションでのタグ出力
    global $paged;
    if ( get_previous_posts_link() ){
      echo '<link rel="prev" href="'.get_pagenum_link( $paged - 1 ).'" />'.PHP_EOL;
    }
    if ( get_next_posts_link() ){
      echo '<link rel="next" href="'.get_pagenum_link( $paged + 1 ).'" />'.PHP_EOL;
    }
  }
}
//適切なページのヘッダーにnext/prevを表示
add_action( 'wp_head', 'rel_next_prev_link_tags' );

//分割ページ(マルチページ)URLの取得
//参考ページ:http://seophp.net/wordpress-fix-rel-prev-and-rel-next-without-plugin/
function generate_multipage_url($rel='prev') {
  global $post;
  $url = '';
  $multipage = check_multi_page();
  if($multipage[0] > 1) {
    $numpages = $multipage[0];
    $page = $multipage[1] == 0 ? 1 : $multipage[1];
    $i = 'prev' == $rel? $page - 1: $page + 1;
    if($i && $i > 0 && $i <= $numpages) {
      if(1 == $i) {
        $url = get_permalink();
      } else {
        if ('' == get_option('permalink_structure') || in_array($post->post_status, array('draft', 'pending'))) {
          $url = add_query_arg('page', $i, get_permalink());
        } else {
          $url = trailingslashit(get_permalink()).user_trailingslashit($i, 'single_paged');
        }
      }
    }
  }
  return $url;
}

//分割ページ(マルチページ)かチェックする
function check_multi_page() {
  $num_pages    = substr_count(
      $GLOBALS['post']->post_content,
      '<!--nextpage-->'
  ) + 1;
  $current_page = get_query_var( 'page' );
  return array ( $num_pages, $current_page );
}

基本的に、コピペ一発でカスタマイズできます。一応、Twenty Fifteenテーマで動作を確認しました。

Simplicityの1.8.8でこの機能は実装予定なので、Simplicityのカスタマイズでは利用しないことをおすすめします。そうしないと、バージョンアップした際、関数名が衝突してエラーが出ると思います。
check_multi_page()関数を使わず、$multipageグローバル変数を使ったもう少し効率の良い方法のコードはコメント欄に書きました。$multipage等を使った方法はコメント欄を参照してください。

参考 WordPressのrel=“prev”とrel=“next”をプラグインなしで最適化する | SEOPHP

参考 Simplicityで独自に変更したSEO施策

動作確認

先に挙げたポイントごとに動作を確認してみたいと思います。

投稿ページ(シングルページ)でのタグ出力

これにより通常の投稿ページでは、以前Wordpressデフォルト機能で以下のようなタグが出力されていたのが出力されなくなりました。

<link rel="prev" href="http://exsample.com/wordpress/post-434/" />
<link rel="next" href="http://exsample.com/wordpress/post-436/" />

続き物ページでのタグ出力

「1ページを複数に分割した続きものの投稿」には、next/prevタグが出力されるようになりました。

以下は、続き物分割ページの2ページ目を表示させた場合のタグ出力例です。

<link rel="prev" href="http://exsample.com/wordpress/series-of-articles/" />
<link rel="next" href="http://exsample.com/wordpress/series-of-articles/3/" />

一覧(ページネーション)でのタグ出力

トップの一覧や、カテゴリの一覧などでもnext/prevタグが出力されるようになりました。

以下は、トップ一覧の3ページ目を表示させたタグ出力例です。

<link rel="prev" href="http://exsample.com/wordpress/page/2/" />
<link rel="next" href="http://exsample.com/wordpress/page/4/" />

まとめ

こんな感じで、Google公式が推奨する続き物ページにnext/prevタグをWordpressに実装してみました。

加えて、All in One SEO Packなども行っている、一覧ページのページネーション分割にもnext/prevタグを追加しました。

これにより、どれほどのSEO的に効果があるのかはGoogleにしかわかりません。とりあえず、しばらく自分のページで試してみたいと思います。

僕もSEOに関しては、特別詳しいわけではなく、とても熟知しているとは言い難いです。ですので間違っている可能性もあるかもしれません。もし、おかしな場合は、コメントなどで指摘していただけると幸いです。

スポンサーリンク
レクタングル(大)広告
レクタングル(大)広告

スポンサーリンク

『続き物ページを表す「rel=”next” rel=”prev”」タグをWordPressで最適化して利用するカスタマイズ方法』へのコメント

  1. 名前:Ben.P 投稿日:2016/09/29(木) 08:51:51 ID:2b60b263e

    (rel=’prev’ rel=’next’) について色々調べていて行き着きました。

    やりたいことはここで書かれていることですごく参考になります。

    ただ、WPの仕様変更なのか、previous_post_linkで記事下にページャー追加すると (rel=’prev’ rel=’next’) が付加されてしまいますね。

    ヘッダーの記述は、何もしなくても多分出力されなくなっています。

    可能ならprevious_post_link(‘%link’)で出力した際の (rel=’prev’ rel=’next’) を削除したいのですが、なかなか見当たらなくご質問させていただきました。

    もし分かるようであれば教えて頂けると助かります。

    よろしくお願いいたします。

  2. アバター画像 名前:わいひら 投稿日:2016/09/29(木) 19:18:59 ID:5b165dffb

    おそらく、こんな感じでいけるんじゃなかろうかと思います。

    //previous_post_linkやnext_post_link関数からrel属性を取り除く
    function remove_rel_prev_next($tag) {
      $tag = str_replace(' rel="prev"', '', $tag);
      $tag = str_replace(' rel="next"', '', $tag);
      return $tag;
    }
    add_filter('previous_post_link', 'remove_rel_prev_next');
    add_filter('next_post_link', 'remove_rel_prev_next');
  3. 名前:Ben.P 投稿日:2016/10/01(土) 17:50:00 ID:37ba5a1e6

    ありがとうございます。
    早速実装できました。

  4. 名前:ひで 投稿日:2017/02/02(木) 11:38:53 ID:e417b2a1f

    何度もこちらを拝見させて参考にしています。

    Simplicity2でプラグインのWP-PageNavi を使いたいのですが
    入れてみたのですが表示されません。
    ここの記事の事が関係してるのでしょうか?

    出来れば個別記事でページを分割して 前のページ<>
    という風に表示させたいのですが出来ません。

    色々調べたのですがどれをやっても表示されません。

    あと、過去記事も自動で分割ページを入れるプラグインAutomatically Paginate Posts
    も表示されませんでした。

    もしおわかりでしたら教えて下さいませ。

    よろしくお願いします。

  5. アバター画像 名前:わいひら 投稿日:2017/02/03(金) 21:56:29 ID:a170179f5

    僕は、どちらのプラグインを使用したことがないので、関係はわからないです。
    エラーメッセージには書かれているのでしょうか?(エラーメッセージが出てない場合は、Wordpressのデバックモードにしする必要があるかもしれません)

    関係があるかないかをハッキリさせるには、当記事のカスタマイズ部分をすべて削除してプラグインが動作するかどうかでわかると思います。

  6. 名前:Mirucon 投稿日:2017/12/07(木) 05:22:34 ID:1b3a85165

    ページが分割されているかどうかの判定は、`global $multipage;` で行うのが一番パフォーマンス的にもいいかと思います。もし既にテーマ内では修正済みでしたらすみません

  7. アバター画像 名前:わいひら 投稿日:2017/12/07(木) 23:17:47 ID:d9b971b18

    確かに。
    そんないいグローバル変数があったんですね。
    とりあえず以下のグローバル変数を使用して、
    global $multipage;
    global $page;
    global $numpages;
    こんな感じにしてみました。

    //デフォルトのrel="next"/"prev"を消す
    remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
    
    ////ページネーションと分割ページ(マルチページ)タグを出力
    function rel_next_prevlink_tags() {
      //1ページを複数に分けた分割ページ
      if(is_single() || is_page()) {
        global $wp_query;
        global $multipage;
        //$multipage = check_multi_page();
        if($multipage) {
          $prev = generate_multipage_url('prev');
          $next = generate_multipage_url('next');
          if($prev) {
            echo ''.PHP_EOL;
          }
          if($next) {
            echo ''.PHP_EOL;
          }
        }
      } else{
        //トップページやカテゴリページなどの分割ページの設定
        global $paged;
        if ( get_previous_posts_link() ){
          echo ''.PHP_EOL;
        }
        if ( get_next_posts_link() ){
          echo ''.PHP_EOL;
        }
      }
    }
    //分割ページのみnext/prevを表示
    add_action( 'wp_head', 'rel_next_prevlink_tags' );
    
    //分割ページ(マルチページ)URLの取得
    //参考ページ:
    //http://seophp.net/wordpress-fix-rel-prev-and-rel-next-without-plugin/
    function generate_multipage_url($rel='prev') {
      global $post;
      global $multipage;
      global $page;
      global $numpages;
      $url = '';
      //$multipage = check_multi_page();
      if($multipage) {
        //$numpages = $multipage[0];
        //$page = $multipage[1] == 0 ? 1 : $multipage[1];
        $i = 'prev' == $rel? $page - 1: $page + 1;
        if($i && $i > 0 && $i <= $numpages) {
          if(1 == $i) {
            $url = get_permalink();
          } else {
            if ('' == get_option('permalink_structure') || in_array($post->post_status, array('draft', 'pending'))) {
              $url = add_query_arg('page', $i, get_permalink());
            } else {
              $url = trailingslashit(get_permalink()).user_trailingslashit($i, 'single_paged');
            }
          }
        }
      }
      return $url;
    }
    

    コードが正しければ、本文からカウントを取得する必要がないので、こっちのが全然スマートですね。

  8. 名前:Mirucon 投稿日:2017/12/09(土) 14:41:05 ID:5c76577d7

    実は僕のプラグインでこのような実装をしたく、このページを参考にさせていただいてました。大体僕のコードもそんな感じのに落ち着いてます。(このページを参考にしたので当然ですが…

    https://github.com/Mirucon/coldbox-addon/blob/223cc9700ce0080a127733ec4d396c40dd9a04e4/inc/meta.php#L51

  9. アバター画像 名前:わいひら 投稿日:2017/12/10(日) 13:32:13 ID:c49b24aa9

    今回、自分のテーマの動作を見直す良い機会になりました。
    教えていただき、ありがとうございます!