[Astro] Google Tag Manager(GTM)を静的サイトに入れる

Tech
[Astro] Google Tag Manager(GTM)を静的サイトに入れる

WordPress 時代に使っていた Google Tag Manager(GTM) を、Astro でも入れ直しました。GTM のスニペットは「<head> 用」と「<body> 直後の noscript 用」の2つがあるので、その両方を Astro で素直に配置します。

コンポーネントにまとめる

GTM の head 用スニペットをコンポーネント化します。ID はサイト定数から渡す形に。Astro にバンドルさせたくないので is:inline を付けます。

---
// src/components/GoogleTagManager.astro
import { SITE } from '@/data/site';
---
<!-- Google Tag Manager -->
<script is:inline define:vars={{ gtmId: SITE.gtmId }}>
  (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
  new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
  j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
  'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
  })(window,document,'script','dataLayer',gtmId);
</script>
<!-- End Google Tag Manager -->

define:vars で frontmatter の値(gtmId)をインライン script に渡せるのが便利です。ID は src/data/site.ts あたりに置いておきます。

export const SITE = {
  // ...
  gtmId: 'GTM-XXXXXXX',
} as const;

レイアウトに配置する

<head>できるだけ上にコンポーネントを置き、<body> 直後に noscript 版を置きます。

---
// src/layouts/BaseLayout.astro
import GoogleTagManager from '@/components/GoogleTagManager.astro';
import { SITE } from '@/data/site';
---
<html lang="ja">
<head>
  <GoogleTagManager />
  <meta charset="utf-8" />
  <!-- ... -->
</head>
<body>
  <!-- Google Tag Manager (noscript) -->
  <noscript>
    <iframe src={`https://www.googletagmanager.com/ns.html?id=${SITE.gtmId}`}
      height="0" width="0" style="display:none;visibility:hidden"></iframe>
  </noscript>
  <slot />
</body>
</html>

noscript の iframe には is:inline は不要(script ではないので Astro がそのまま出力します)。

確認

ビルド後の HTML に GTM が入っているか見ます。

npm run build
grep -o "googletagmanager.com/gtm.js" dist/index.html
grep -o "GTM-XXXXXXX" dist/index.html

本番では GTM プレビュー(Tag Assistant)で発火を確認するのが確実です。

メモ

  • is:inline を忘れると Astro が script をバンドルしようとして GTM の意図どおりに動かないことがある。インラインのまま出すのがポイント。
  • ID をコンポーネントに直書きせず SITE.gtmId に集約しておくと、head とも noscript とも共有できて管理が楽。
  • 静的サイトでも GTM はクライアント側で動くので、WordPress 時代の設定(タグ・トリガー)はそのまま使い回せました。

Astro, GTM, アクセス解析