GA4

GTMタグの運用を効率化!共通タグ + パラメータで個別計測する方法

お疲れ様です。みんみんです。
今回は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タグの効率的な運用方法についてご紹介しました。
質問や改善案があれば、ぜひコメントで教えてください!

この記事を気に入ったら