枠のどこにも「広告」と書いていなかった
管理しているサイトで、記事の下に出しているアフィリエイトの枠を見直していたときのことです。この枠は自作のプラグインで出していて、いくつかのキーワードを Amazon の検索のリンクにして並べるだけの小さなものなのですが、リンクから買い物があるとサイトに紹介料が入る作りなのに、枠のどこにも広告だと分かる表示がありませんでした。
2023 年 10 月からは、広告であることが分からない表示が景品表示法の規制の対象になっています。そこで、プラグインを直して、枠の頭に「広告」、下にアソシエイトの一文と開示のページへのリンクを出すようにし、同じプラグインを入れているほかのサイトにも入れ替えました。
ステルスマーケティングの規制について
消費者庁のページによると、令和 5 年(2023 年)10 月 1 日から、「一般消費者が事業者の表示であることを判別することが困難である表示」が景品表示法の不当表示として告示され、いわゆるステルスマーケティングが規制の対象になりました。規制されるのは、広告であるのに、一般消費者が広告だと分からないものです。規制を受けるのは広告を出す事業者で、依頼を受けて投稿するインフルエンサーなどの第三者は対象ではないとされています。
アフィリエイトのリンクをどう表示すればよいかは、ページの中に具体的な文言の例があるわけではなく、運用基準や Q&A などの資料に分かれています。この記事は、管理しているサイトでこう表示した、という作業の記録で、法律の判断を示すものではありません。くわしくは、下の参考にある消費者庁のページと資料を見てください。
枠に足したもの
| 場所 | 中身 |
|---|---|
| 枠の頭 | 「広告」の小さなラベルと、枠の見出し |
| リンク | rel="sponsored nofollow noopener" と target="_blank" |
| 枠の下 | 「Amazonのアソシエイトとして、(サイト名)は適格販売により収入を得ています。」の一文 |
| 一文のあと | 開示のページ(広告についての説明のページ)へのリンク。設定に URL があるときだけ |
下の一文は、Amazon のアソシエイト・プログラムで、サイトに表示するように求められている文です。サイト名は get_bloginfo( 'name' ) から入れるので、どのサイトに入れても、そのサイトの名前になります。
枠の HTML を作る部分
プラグインのうち、枠の HTML を作る部分を、例の名前にして短くしたものが次のコードです。ショートコードから、設定の値やキーワードを渡して呼んでいます。
<?php
// 枠の HTML を作る(ショートコードから呼ぶ)
function my_amazon_box_html( $words, $title, $tag, $disclosure_url ) {
if ( ! $words ) {
return '';
}
$html = '<div class="my-amazon-box">';
$html .= '<div class="my-amazon-box__head"><span class="my-amazon-box__pr">広告</span>' . esc_html( $title ) . '</div>';
$html .= '<ul>';
foreach ( $words as $word ) {
$url = 'https://www.amazon.co.jp/s?k=' . rawurlencode( $word );
if ( '' !== $tag ) {
$url .= '&tag=' . rawurlencode( $tag );
}
$html .= '<li><a href="' . esc_url( $url ) . '" target="_blank" rel="sponsored nofollow noopener">' . esc_html( $word ) . '</a></li>';
}
$html .= '</ul>';
$html .= '<p class="my-amazon-box__note">Amazonのアソシエイトとして、' . esc_html( get_bloginfo( 'name' ) ) . 'は適格販売により収入を得ています。';
if ( '' !== $disclosure_url ) {
$html .= '<a href="' . esc_url( $disclosure_url ) . '">広告について</a>';
}
$html .= '</p></div>';
return $html;
}
| 書き方 | 役目 |
|---|---|
esc_html( $title )・esc_html( $word ) |
見出しとキーワードを、HTML として動かない形にして出す |
rawurlencode( $word ) |
キーワードを検索の URL に入れる形にする。空白や記号もそのまま検索の文字になる |
esc_url( $url ) |
URL を、属性に出してよい形にする。& は & になる |
rel="sponsored nofollow noopener" |
sponsored で広告のリンクだと検索エンジンに伝える。nofollow は sponsored を読まない仕組み向け。noopener は新しいタブから元のページを操作させない |
get_bloginfo( 'name' ) |
一文の中のサイト名 |
'' !== $disclosure_url |
開示のページの URL を決めたサイトだけ、リンクを出す |
はじめのころのコードでは、キーワードを esc_html() にかけてから URL に入れていたため、& などを含むキーワードで検索の文字が変わってしまう作りになっていました。URL に入れる値は rawurlencode()、できた URL は esc_url()、画面に出す文字は esc_html() と、使う場所ごとに分けています。
サイトごとに決められる設定
同じプラグインを、内容の違う複数のサイトに入れているため、サイトごとに変える値は設定の画面で決められるようにしました。保存のときに、値の形をそろえています。
<?php
// 設定の値(サイトごと)。保存のときに形をそろえる
add_action(
'admin_init',
function () {
register_setting(
'my_amazon_box',
'my_amazon_box_options',
array(
'type' => 'array',
'sanitize_callback' => function ( $in ) {
$in = is_array( $in ) ? $in : array();
return array(
'tag' => isset( $in['tag'] ) ? sanitize_text_field( $in['tag'] ) : '',
'title' => isset( $in['title'] ) ? sanitize_text_field( $in['title'] ) : '',
'disclosure' => isset( $in['disclosure'] ) ? esc_url_raw( trim( $in['disclosure'] ) ) : '',
'words' => isset( $in['words'] ) ? sanitize_textarea_field( $in['words'] ) : '',
);
},
)
);
}
);
// 「,」「、」・改行で区切ったキーワードの並び
function my_amazon_box_split( $text ) {
$parts = preg_split( '/[,、\r\n]+/u', (string) $text );
return array_values( array_filter( array_map( 'trim', $parts ), 'strlen' ) );
}
| 設定 | 使い方 |
|---|---|
| トラッキング ID | 検索の URL の tag に入れる |
| 見出し | 枠の頭の文字。サイトの内容に合わせる |
| 開示のページの URL | esc_url_raw() で URL として保存する。空ならリンクを出さない |
| 検索のキーワード | 「,」「、」・改行で区切って書く。ショートコードの属性でも渡せる |
検索のキーワードを、サイトの内容に合う本に変えた
もとの枠は、その日のトレンドのキーワードを外から取ってきて並べる作りでした。ところが、サイトの内容と関係のない商品が並ぶことが多く、読んだ人の役に立つとは言いにくい状態でした。そこで、サイトごとに、内容に合う本を探すキーワード(たとえば「(テーマ)入門」「(テーマ)本」のような形)を設定で決められるようにしました。
カテゴリーごとに内容がはっきり分かれているサイトでは、テーマの側でカテゴリーを見て、ショートコードの属性でキーワードを渡しています。設定もキーワードもないときだけ、もとのトレンドのキーワードを使います。
広告を出さないと決めたサイトでは
サイトによっては、枠そのものを出さないことにしました。このときは、先にテーマから枠を出す行を外し、そのあとでプラグインを無効にしています。順番を逆にすると、テーマに書いた do_shortcode() がショートコードを見つけられず、角かっこのショートコードの文字がそのままページに出てしまうためです。外したあとは、記事のページで枠も、ショートコードの文字も出ないことを確かめました。
確かめた結果
本番から複製した作業環境で、この記事の例のコードを検証用スクリプトから読み込み、出る HTML を見ました。
| 確かめたこと | 結果 |
|---|---|
php -l |
例のコードはエラーなし |
| 「,」「、」・改行・空の行がまじったキーワード | 空のものを除いて 4 個に分かれた |
<script>& を含むキーワードと見出し |
画面の文字は <script>& に、URL は %3Cscript%3E%26 になった |
開示のページの URL の & |
& になった |
| キーワードがないとき | 何も出さない(空の文字) |
今回検証したサイトでは、外部リンクを書き換えるプラグインが入っていて、出力されたリンクに external noreferrer が足され、開示のページへのリンクにも target="_blank" と nofollow が付きました。sponsored はそのまま残っていましたが、こうしたプラグインを使っているサイトでは、ページに出た最後の HTML で rel を確かめておくと安心です。本番のサイトでは、記事のページで「広告」のラベル、アソシエイトの一文、開示のページへのリンクが出ていることを確かめました。
気をつけること
- どう表示すれば足りるかは、消費者庁の資料と、使っているアフィリエイトのサービスの規約を確かめて決める
- 今回は「広告」の表示を枠の外ではなく枠の頭に置き、リンクと一緒に目に入るようにした
- キャッシュのプラグインを使っているサイトでは、プラグインを入れ替えたあとにキャッシュを消してから確かめる
- 枠を出さないサイトでは、テーマから外してからプラグインを無効にする
まとめ
- アフィリエイトの枠には、頭に「広告」、下にアソシエイトの一文と開示のページへのリンクを出した
- リンクには
rel="sponsored nofollow noopener"を付けた - URL に入れる値は
rawurlencode()、URL はesc_url()、画面の文字はesc_html()と分ける - 見出し・開示のページ・検索のキーワードはサイトごとに設定で決め、内容に合う本のキーワードにした
- 規制のくわしい中身は、消費者庁のページで確かめる

