2026年8月6日

2026年8月6日

WordPressで関連記事を表示する方法|プラグイン・Jetpack・自作コードの使い分け

記事を読み終えた読者に、同じ話題の別の記事を案内するのが「関連記事」です。WordPress 本体には関連記事を選んで表示する機能が無いため、プラグインを使うか、テーマにコードを追加して作ります(2026年10月時点)。

この記事では、次の3つの方法と、それぞれの向き・不向きを説明します。

方法 向いている場合 注意点
関連記事プラグイン コードを書かずに、本文の内容から関連度を計算したい 記事数が多いと、関連度の計算がデータベースの負担になる
Jetpack の関連投稿 すでに Jetpack を使っている WordPress.com との連携が必要。候補が3件未満だと表示されない
自作コード(WP_Query) 同じカテゴリー・タグの記事を出せば足りる。表示を細かく決めたい テーマの更新で消えない場所に書く

テーマによっては、テーマの設定画面に関連記事の表示機能が入っています。先にテーマの設定を確認し、無い場合に以下の方法を選びます。

方法1:関連記事プラグインを使う

公式ディレクトリで更新が続いているものとして、Contextual Related Posts があります。題名・本文・カテゴリー・タグなどから関連する記事を選び、本文の下への自動表示、ブロック(「Related Posts [CRP]」)、ウィジェット、ショートコードで表示できます。

  1. 管理画面の「プラグイン」→「新規プラグインを追加」で「Contextual Related Posts」を検索し、インストールして有効化する
  2. 追加される設定画面で、表示する件数、表示する場所(本文の後など)、除外するカテゴリーやタグ、サムネイルの有無を決める
  3. 記事を開き、本文の下に関連記事が出ることを確かめる

WP-CLI を使える場合は、次のコマンドでインストールと有効化ができます。

wp plugin install contextual-related-posts --activate

古くから使われている YARPP(Yet Another Related Posts Plugin) は、2026年10月時点で公式ディレクトリに「直近3回のメジャーリリースでテストされていない」と表示されています。新しく入れる場合は、更新が続いているプラグインを選ぶほうが安全です。

方法2:Jetpack の関連投稿を使う

Jetpack を使っているサイトでは、Jetpack の関連投稿(Related Posts)を使えます。関連度の計算は WordPress.com 側のサーバーで行われるため、自分のサーバーの負担は増えません。

  1. 管理画面で「Jetpack」→「設定」→「トラフィック」を開く
  2. 関連コンテンツを投稿の後に表示する項目(英語表示では「Show related content after posts」)をオンにする
  3. クラシックテーマでは本文の下に自動で表示される。ブロックテーマでは、サイトエディターで投稿のテンプレートに「関連投稿」ブロックを追加する

Jetpack の説明によると、関連投稿は Jetpack と WordPress.com の連携が動いていないと表示されず、条件に合う候補が3件以上見つからない場合も表示されません。結果は最大12時間キャッシュされるため、新しい記事が候補に入るまで時間がかかることがあります。

方法3:同じカテゴリー・タグの記事をコードで表示する

「同じカテゴリーかタグの、新しい記事を4件」のような単純な関連記事なら、プラグインを使わずに作れます。次のコードは、子テーマの functions.php か、wp-content/mu-plugins/ に置いた PHP ファイルに書きます(親テーマに直接書くと、テーマの更新で消えます)。

<?php
/**
 * 同じカテゴリーまたはタグの記事IDを取得する
 */
function lsc_get_related_post_ids( $post_id, $count = 4 ) {
	$cache_key = 'lsc_related_' . $post_id;
	$ids       = get_transient( $cache_key );

	if ( false !== $ids ) {
		return $ids;
	}

	$tax_query = array( 'relation' => 'OR' );

	$cat_ids = wp_get_post_categories( $post_id );
	if ( $cat_ids ) {
		$tax_query[] = array(
			'taxonomy' => 'category',
			'field'    => 'term_id',
			'terms'    => $cat_ids,
		);
	}

	$tag_ids = wp_get_post_tags( $post_id, array( 'fields' => 'ids' ) );
	if ( $tag_ids ) {
		$tax_query[] = array(
			'taxonomy' => 'post_tag',
			'field'    => 'term_id',
			'terms'    => $tag_ids,
		);
	}

	if ( count( $tax_query ) < 2 ) {
		return array();
	}

	$query = new WP_Query(
		array(
			'post_type'           => 'post',
			'post_status'         => 'publish',
			'posts_per_page'      => $count,
			'post__not_in'        => array( $post_id ),
			'tax_query'           => $tax_query,
			'ignore_sticky_posts' => true,
			'no_found_rows'       => true,
			'fields'              => 'ids',
		)
	);

	$ids = $query->posts;
	set_transient( $cache_key, $ids, 12 * HOUR_IN_SECONDS );

	return $ids;
}

/**
 * 投稿の本文の後に関連記事を追加する
 */
function lsc_append_related_posts( $content ) {
	if ( ! is_singular( 'post' ) || ! in_the_loop() || ! is_main_query() ) {
		return $content;
	}

	$ids = lsc_get_related_post_ids( get_the_ID() );
	if ( empty( $ids ) ) {
		return $content;
	}

	$html = '<section class="lsc-related"><h2>関連記事</h2><ul>';
	foreach ( $ids as $id ) {
		$html .= sprintf(
			'<li><a href="%1$s">%2$s<span>%3$s</span></a></li>',
			esc_url( get_permalink( $id ) ),
			get_the_post_thumbnail( $id, 'thumbnail' ),
			esc_html( get_the_title( $id ) )
		);
	}
	$html .= '</ul></section>';

	return $content . $html;
}
add_filter( 'the_content', 'lsc_append_related_posts' );

/**
 * 記事を保存したら、その記事の関連記事のキャッシュを消す
 */
function lsc_clear_related_cache( $post_id ) {
	delete_transient( 'lsc_related_' . $post_id );
}
add_action( 'save_post_post', 'lsc_clear_related_cache' );

コードのポイントは次のとおりです。

  • post__not_in で表示中の記事を除き、ignore_sticky_posts で先頭固定の記事が混ざらないようにしています
  • no_found_rows と 'fields' => 'ids' で、ページ送り用の件数計算と不要なデータの取得を省いています
  • 結果を Transients API で12時間保存し、表示のたびに検索しないようにしています。ほかの記事を公開したときは、12時間以内に順次反映されます
  • the_content フィルターで本文の後に追加するため、テンプレートファイルを編集せずに済みます。ブロックテーマでも、WordPress 6.4 以降は投稿のテンプレートがメインループの中で表示されるため、in_the_loop() の判定が働きます

並び順は新しい順です。'orderby' => 'rand' で毎回ランダムにする方法もありますが、データベースで全件を並べ替えるため、記事数が多いサイトでは重くなります。

WP_Query の引数の詳細はWordPressのWP_Queryで記事を取得する方法、キャッシュの仕組みはWordPressのトランジェントAPIでキャッシュを実装する方法を参照してください。

見た目を整えるCSS

子テーマの style.css か、管理画面の「外観」→「カスタマイズ」→「追加CSS」(ブロックテーマではサイトエディターのスタイルの「追加CSS」)に書きます。

.lsc-related ul {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
	gap: 16px;
	padding: 0;
	list-style: none;
}
.lsc-related img {
	display: block;
	width: 100%;
	height: auto;
}

表示を確かめる

  • ログアウトした状態(またはシークレットウィンドウ)で記事を開き、関連記事が出ること、表示中の記事が含まれないことを確かめる
  • キャッシュプラグインを使っている場合は、ページキャッシュを削除してから確かめる
  • 固定ページや一覧ページに表示されていないことを確かめる

注意点

  • 関連記事の数を増やすほど、ページが長くなり画像の読み込みも増えます。4〜6件程度から始め、クリックされているかをアクセス解析で確かめて調整します
  • 関連度を本文から計算するプラグインは、記事数が多いとデータベースの負担が大きくなることがあります。表示が遅くなった場合は、プラグインのキャッシュ設定を確かめるか、計算を外部で行う Jetpack や、単純なコードの方法を検討します
  • 同じ機能のプラグインやテーマの機能を2つ同時に有効にすると、関連記事が二重に表示されます

まとめ

  • WordPress 本体には関連記事の機能が無いので、テーマの機能、プラグイン、Jetpack、自作コードから選ぶ
  • 本文から関連度を計算したいなら Contextual Related Posts などのプラグイン、Jetpack を使っているなら Jetpack の関連投稿
  • 同じカテゴリー・タグの記事で足りるなら、WP_Query と Transients API で軽く作れる
  • 表示はログアウトした状態で、キャッシュを消してから確かめる

お気軽にご相談ください

お見積りへ お問い合わせへ
▲