2026年10月12日

2026年10月12日

WordPressでクーポンサイトを構築する方法:投稿設計・期限切れ処理・広告表記まで

WordPressでクーポン・セール情報をまとめるサイトを作るなら、クーポンを専用のカスタム投稿タイプにし、ストアをタクソノミー、コード・有効期限・リンク先をカスタムフィールドで持たせる構成が扱いやすい方法です。この記事では、その投稿設計、期限切れクーポンを一覧から外す処理、コードをコピーできるボタン、アフィリエイトリンクの扱いと広告表記、検索エンジン対策の注意点までを順に説明します。

なお、ここでいうクーポンサイトは「各ストアのクーポンを紹介するメディア」です。自分のネットショップで割引クーポンを発行したい場合は、WooCommerceのクーポン機能を使う別の話になります。

構築方法の選択肢

クーポンサイトの作り方は大きく2つです。

  • クーポン向けテーマやプラグインを使う:クーポン表示や期限管理を備えたテーマ・プラグインがあり、早く形にできます。ただし提供元の更新が止まると乗り換えが大変になるため、更新頻度とサポート状況を確認してから選びます
  • カスタム投稿タイプで自作する:必要な機能だけを作るので軽く、テーマを替えてもデータ構造が残ります。この記事ではこちらを解説します

自作する場合でも、項目の入力画面はAdvanced Custom Fields(ACF)などのフィールド系プラグインで作り、表示と期限処理だけをコードで書く組み合わせが現実的です。

データ構造を決める

クーポン1件が持つ情報を先に整理します。

項目 持たせ方 例
クーポン名・説明 投稿のタイトル・本文 初回購入10%オフ
ストア タクソノミー store 〇〇ストア
ジャンル タクソノミー(カテゴリー等) ファッション
クーポンコード カスタムフィールド coupon_code WELCOME10
有効期限 カスタムフィールド coupon_expires(Y-m-d) 2026-12-31
利用先URL カスタムフィールド coupon_url ストアの該当ページ

ストアをタクソノミーにしておくと、/store/ストア名/ のようなストア別一覧ページが自動で作れます。検索流入の多くはストア名での検索なので、ストアのページにはストアの特徴や利用時の注意など、独自の説明文を書けるようにしておくと価値が上がります。

投稿タイプ・タクソノミー・フィールドを登録する

次のコードは専用プラグインかmu-plugin(wp-content/mu-plugins/)に置きます。テーマに書くとテーマ変更でクーポンが表示されなくなるためです。作業前にバックアップを取り、ステージング環境で試してください。

<?php
/**
 * Plugin Name: Coupon Site Core
 */

add_action( 'init', function () {
	register_post_type( 'coupon', array(
		'labels'       => array( 'name' => 'クーポン', 'singular_name' => 'クーポン' ),
		'public'       => true,
		'has_archive'  => true,
		'rewrite'      => array( 'slug' => 'coupons' ),
		'supports'     => array( 'title', 'editor', 'custom-fields' ),
		'show_in_rest' => true,
	) );

	register_taxonomy( 'store', 'coupon', array(
		'labels'       => array( 'name' => 'ストア', 'singular_name' => 'ストア' ),
		'public'       => true,
		'rewrite'      => array( 'slug' => 'store' ),
		'show_in_rest' => true,
	) );

	$can_edit = function () {
		return current_user_can( 'edit_posts' );
	};

	register_post_meta( 'coupon', 'coupon_code', array(
		'type'              => 'string',
		'single'            => true,
		'show_in_rest'      => true,
		'sanitize_callback' => 'sanitize_text_field',
		'auth_callback'     => $can_edit,
	) );
	register_post_meta( 'coupon', 'coupon_expires', array(
		'type'              => 'string',
		'single'            => true,
		'show_in_rest'      => true,
		'sanitize_callback' => 'sanitize_text_field',
		'auth_callback'     => $can_edit,
	) );
	register_post_meta( 'coupon', 'coupon_url', array(
		'type'              => 'string',
		'single'            => true,
		'show_in_rest'      => true,
		'sanitize_callback' => 'esc_url_raw',
		'auth_callback'     => $can_edit,
	) );
} );

register_post_meta() でフィールドを登録しておくと、保存時のサニタイズが効き、REST API経由でブロックエディターからも扱えます。登録後は「設定」→「パーマリンク」を開いて保存し直し、/coupons/ や /store/ のURLを有効にします。

期限切れのクーポンを一覧から外す

クーポンサイトで信頼を失う最大の原因は、使えないクーポンが並んでいることです。一覧ページのメインクエリを pre_get_posts で調整し、有効期限が今日以降のもの、または期限が設定されていないものだけを表示します。

add_action( 'pre_get_posts', function ( $query ) {
	if ( is_admin() || ! $query->is_main_query() ) {
		return;
	}
	if ( $query->is_post_type_archive( 'coupon' ) || $query->is_tax( 'store' ) ) {
		$query->set( 'meta_query', array(
			'relation' => 'OR',
			array(
				'key'     => 'coupon_expires',
				'value'   => wp_date( 'Y-m-d' ),
				'compare' => '>=',
				'type'    => 'DATE',
			),
			array(
				'key'     => 'coupon_expires',
				'compare' => 'NOT EXISTS',
			),
		) );
	}
} );

wp_date() はサイトのタイムゾーン設定で日付を返すため、日本時間の日付で比較できます。期限は 2026-12-31 のような年-月-日の形式でそろえて入力してください。形式がばらつくと正しく比較できません。

クーポンが数万件規模になると、カスタムフィールドでの絞り込みは遅くなりがちです。その場合は、WP-Cronで1日1回期限切れのクーポンを探して「期限切れ」タームを付けるなど、表示時ではなく事前に振り分ける方式に切り替えます。期限切れページを削除するか残すかは、ストア側で同じキャンペーンが再開されることもあるため、「終了しました」と明示して残し、最新のクーポンへ案内する運用も検討してください。

コードのコピーボタンとリンクの出力

単一クーポンのテンプレートでは、値を出力するときに用途に合ったエスケープを使います。

<?php
$code = get_post_meta( get_the_ID(), 'coupon_code', true );
$url  = get_post_meta( get_the_ID(), 'coupon_url', true );
?>
<?php if ( $code ) : ?>
	<p class="coupon-code"><?php echo esc_html( $code ); ?></p>
	<button type="button" class="coupon-copy" data-code="<?php echo esc_attr( $code ); ?>">コードをコピー</button>
<?php endif; ?>
<?php if ( $url ) : ?>
	<a href="<?php echo esc_url( $url ); ?>" rel="sponsored noopener" target="_blank">ストアで使う</a>
<?php endif; ?>

コピー処理は小さなJavaScriptで足ります。Clipboard APIはHTTPSのページでしか動かないため、サイトが常時SSL化されていることが前提です。

document.addEventListener( 'click', function ( event ) {
	const button = event.target.closest( '.coupon-copy' );
	if ( ! button || ! navigator.clipboard ) {
		return;
	}
	navigator.clipboard.writeText( button.dataset.code ).then( function () {
		button.textContent = 'コピーしました';
	} );
} );

スクリプトは子テーマの functions.php などで読み込みます。WordPress 6.3以降は strategy 引数で defer を指定できます。

add_action( 'wp_enqueue_scripts', function () {
	if ( is_singular( 'coupon' ) ) {
		wp_enqueue_script(
			'coupon-copy',
			get_stylesheet_directory_uri() . '/js/coupon-copy.js',
			array(),
			'1.0.0',
			array( 'strategy' => 'defer', 'in_footer' => true )
		);
	}
} );

「コードを見る」を押すと別タブでストアを開き、元のタブでコードを表示する、という仕掛けはよく見かけます。ただし、利用者がクリックしていないのにアフィリエイトのCookieを付ける行為はASP(アフィリエイト・サービス・プロバイダ)の規約違反になるのが一般的です。リンクは利用者が明示的に押したときだけ開くようにします。

広告表記と提携先の規約

クーポンサイトの多くはアフィリエイト収益で運営されます。2023年10月から、広告であることを隠した表示(いわゆるステルスマーケティング)が景品表示法の不当表示として規制されています。サイト全体とクーポンごとに「広告」「PR」などの表記を分かりやすく入れ、広告の方針をまとめたページを用意します。

また、提携先によってはクーポンコードの掲載を許可制にしていたり、ASP経由での掲載を禁止していたりします。掲載前にASPと提携先の規約を確認し、許可されたコードだけを載せてください。

検索エンジンとの付き合い方

Googleは、他社のコンテンツを借りて上位表示を狙うサイトの評判の不正使用や、内容の薄い大量ページを品質上の問題として扱っています。クーポンを並べるだけのページは評価されにくいため、次のような独自の情報を加えます。

  • 最終確認日と、実際に使えたかどうかの確認結果
  • 対象商品・最低購入金額・併用可否などの利用条件
  • ストアの支払い方法や送料など、利用前に知っておきたい情報

外部リンクには rel="sponsored" を付け、検索エンジンに広告リンクであることを伝えます。どの対策も順位を保証するものではなく、利用者にとって役立つ情報を増やすことが基本です。検索エンジンの方針は(2026年10月現在)のGoogle検索セントラルの説明をもとにしており、今後変わる可能性があります。

まとめ

  • クーポンはカスタム投稿タイプ、ストアはタクソノミー、コード・期限・URLはカスタムフィールドで持たせる
  • コードはテーマではなく専用プラグインかmu-pluginに書き、保存時のサニタイズと出力時のエスケープを入れる
  • 期限切れのクーポンは pre_get_posts で一覧から外し、件数が多ければ事前に振り分ける方式にする
  • アフィリエイトリンクには rel="sponsored" と広告表記を付け、クリックしていない利用者にCookieを付けない
  • 最終確認日や利用条件など独自の情報を加え、提携先の掲載規約を守る

お気軽にご相談ください

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