お疲れ様です。みんみんです。
今回はGTMタグの運用効率化について、実際の案件で実装した方法をご紹介します。
はじめに
WebサイトやLPで「ボタンごとに個別で計測したい」という要望、
よくあります。
この間担当した大会議LPの案件でも、依頼者から同様の要望をいただきました。
最初に思いついた方法は「各ボタンに別々のクラスを付ける」と簡単に考えていましたが、実際に要件を整理してみると、課題が見えてきました。
直面した課題
実装例(元々の考え)
<!-- MVトップ -->
<a class="gtm_security-2026-spring_contact-mv-top">申込む</a>
<!-- 開催目的 -->
<a class="gtm_security-2026-spring_contact-purpose">申込む</a>
<!-- プログラム -->
<a class="gtm_security-2026-spring_contact-program">申込む</a>
この方法のデメリット
- クラス名がどんどん長くなる
- ボタンが増えるたびにGTM側の設定も増える
- 管理が煩雑になる
- メンテナンス性が悪い
特に、ボタンが今後も増える可能性を考えると、この方法は持続可能ではありません。
改善した実装方法
そこで実装したのが「共通クラス + URLパラメータ」という方法です。
【PHP側の実装コード】
実際のコードはこのように実装しました。
// パラメータ付きリンク生成の仕組み
$entryLinkBase = '/security/conference/2026/contact/';
$baseParams = $access ? ['utm_content' => $access] : [];
// ボタン位置パラメータ付きリンク生成関数
$getEntryLink = fn(string $position = ''): string =>
buildUrlWithParams($entryLinkBase, $position ? [...$baseParams, 'btn' => $position] : $baseParams);
【HTML側の実装コード】
<a href="<?php echo htmlspecialchars($getEntryLink('mv-top'), ENT_QUOTES, 'UTF-8'); ?>"
class="gtm_security-2026-spring_contact">
申込む
</a>
この関数を使えば、ボタンごとに簡単にパラメータ付きのリンクを生成できます。
【セキュリティ対策】
外部からのパラメータを扱う際は、セキュリティ面での配慮が必要です。
今回の実装では、以下の対策を行っています。
チームの先輩から頂いた意見のもとに、コードを修正しました。
1. 入力値のバリデーション(index.php)
$access = filter_input(
INPUT_GET,
'utm_content',
FILTER_VALIDATE_REGEXP,
['options' => ['regexp' => '/^[a-zA-Z0-9_-]+$/']]
);
- filter_input を使用してGETパラメータを安全に取得
- 正規表現で許可する文字を「英数字・アンダースコア・ハイフン」のみに制限
- 不正な文字列が入力された場合は null が返る
- XSSやSQLインジェクション対策として有効
2. is_array による型チェック
function buildUrlWithParams(string $baseUrl, array $params = []): string
{
$p = parse_url($baseUrl);
parse_str($p['query'] ?? '', $existing);
$merged = [...(is_array($existing) ? $existing : []), ...$params];
// ...
}
- parse_str の結果が配列でない場合に備えた安全策
- エッジケース(不正なURL、パースエラー時)でもクラッシュしない
- スプレッド演算子(…)使用前に型を保証
3. 既存パラメータとの共存処理(init.php)
function buildUrlWithParams(string $baseUrl, array $params = []): string
{
$p = parse_url($baseUrl);
parse_str($p['query'] ?? '', $existing);
$merged = [...(is_array($existing) ? $existing : []), ...$params];
return (isset($p['scheme']) ? "{$p['scheme']}://" : '')
. ($p['host'] ?? '')
. (isset($p['port']) ? ":{$p['port']}" : '')
. ($p['path'] ?? '')
. ($merged ? '?' . http_build_query($merged) : '')
. (isset($p['fragment']) ? "#{$p['fragment']}" : '');
}
- 1. parse_url でURLを分解(scheme, host, path, query, fragment)
- 2. parse_str で既存のクエリパラメータを配列に変換
- 3. 既存パラメータと新規パラメータをマージ
- 4. http_build_query で安全にURL文字列を再構築
【流入元も計測する方法】
ボタン位置だけでなく、「どこからLPに来たか」も計測したい場合があります。
これは、発信URLに utm_content パラメータを付けるだけで実現できます。
// LPアクセス時にutm_contentを取得
$access = filter_input(INPUT_GET, 'utm_content', FILTER_VALIDATE_REGEXP,
['options' => ['regexp' => '/^[a-zA-Z0-9_-]+$/']]);
// utm_contentがあれば$baseParamsに保存
$baseParams = $access ? ['utm_content' => $access] : [];
// ボタンリンク生成時に$baseParamsも含める
$getEntryLink = fn(string $position = ''): string =>
buildUrlWithParams($entryLinkBase, $position ? [...$baseParams, 'btn' => $position] : $baseParams);
処理の流れは以下になります。
- 1. ユーザーがメルマガのリンクをクリック
- 2. LP側で utm_content を取得して保存
- 3. ユーザーがMVトップのボタンをクリック
- 4. GA4で計測
運用側がやることは発信URLに utm_content パラメータを付けて配布するだけです。
| 配布先 | URL |
|---|---|
| X(オーガニック投稿) | https://group.gmo/security/conference/2026/?utm_content=x_organic |
| X(広告) | https://group.gmo/security/conference/2026/?utm_content=x_ad |
ユーザーがメルマガ経由でLPに来て、MVトップのボタンをクリックした場合、生成されるリンク先URLはこちらになります。
/security/conference/2026/contact/?utm_content=x_ad&btn=mv-top
この1つのURLから、以下の2つの情報が計測できます:
- utm_content=x_ad → Xの広告から来た
- btn=mv-top → MVトップのボタンで申し込んだ
終わりに
以上、GTMタグの効率的な運用方法についてご紹介しました。
質問や改善案があれば、ぜひコメントで教えてください!
