a/ analytics note .jp

TECH · field log

Astro サイトに GA4 を導入する方法 — is:inline の罠と BaseLayout 設計

Astro で構築した静的サイトに Google Analytics 4(GA4)を正しく導入する手順を解説。script タグの is:inline ディレクティブや共通レイアウトでの一括管理について、実際のハマりどころを交えて紹介します。

· 5 min read · #Astro / #GA4 / #Google Analytics / #アクセス解析 / #静的サイト · AI-assisted · reviewed Share on X はてブ Zennにクロスポスト

はじめに

サイトを公開したら、まず入れておきたいのがアクセス解析。Google Analytics 4(GA4)は無料で使える定番ツールだが、Astro で導入するときにはちょっとした注意点がある。

この記事では、Astro の静的サイトに GA4 タグを導入する手順と、実際にハマったポイントを紹介する。

前提

  • Astro 5.x(output: "static" モード)
  • GA4 の測定 ID を取得済み(例: G-XXXXXXXXXX

Astro の BaseLayout に GA4 タグを配置する手順

Astro では共通レイアウトコンポーネントを作り、全ページで使い回すのが基本。GA4 タグはこのレイアウトの <head> に置くことで、全ページに一括で適用できる。

---
// src/layouts/BaseLayout.astro
interface Props {
  title: string;
  description?: string;
}

const { title, description = "サイトの説明" } = Astro.props;
---

<!doctype html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content={description} />

    <!-- Google tag (gtag.js) -->
    <script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
    <script is:inline>
      window.dataLayer = window.dataLayer || [];
      function gtag(){dataLayer.push(arguments);}
      gtag('js', new Date());
      gtag('config', 'G-XXXXXXXXXX');
    </script>

    <title>{title}</title>
  </head>
  <body>
    <slot />
  </body>
</html>

ここで重要なのが is:inline ディレクティブだ。

Astro の is:inline ディレクティブが GA4 に必須な理由

Astro は <script> タグをデフォルトで JavaScript モジュールとして処理・バンドル する。これは通常のアプリケーションコードにとっては便利な挙動だが、GA4 の gtag スニペットには都合が悪い。

バンドルされると何が起きるかというと:

  1. window.dataLayer の初期化タイミングがずれる — モジュールは defer 扱いになるため、gtag.js の読み込みより後に実行される可能性がある
  2. グローバル関数 gtag() が外部から参照できなくなる — モジュールスコープに閉じ込められる
  3. Tree shaking で意図しないコード除去が起きうる — バンドラが「副作用のないコード」と判断する場合がある

is:inline を付けると、Astro はそのスクリプトを 一切加工せずにそのまま HTML に出力 する。GA4 のようなサードパーティスニペットには必須の設定だ。

<!-- NG: バンドルされてしまう -->
<script>
  window.dataLayer = window.dataLayer || [];
</script>

<!-- OK: そのまま出力される -->
<script is:inline>
  window.dataLayer = window.dataLayer || [];
</script>

Astro ビルド後の GA4 タグ出力確認方法

npm run build

ビルド後の dist/index.html を開いて、以下の 2 点を確認する:

  1. <script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"><head> 内にあること
  2. gtag('config', 'G-XXXXXXXXXX') がインラインスクリプトとして出力されていること
# 簡易チェック
grep "G-XXXXXXXXXX" dist/index.html

2 件ヒットすれば OK。

GA4 リアルタイムレポートでの動作確認

デプロイしたら、GA4 管理画面の「レポート > リアルタイム」で実際にデータが届いているか確認する。ブラウザで自分のサイトにアクセスして、1〜2 分以内にリアルタイムレポートに反映されれば導入完了だ。

もしデータが表示されない場合は、ブラウザの開発者ツール(Network タブ)で collect リクエストが飛んでいるか確認するとデバッグしやすい。

運用のポイント

新規ページは必ず BaseLayout を経由する

GA4 タグを BaseLayout に集約する以上、BaseLayout を使わないページがあると計測漏れが発生する。チーム開発では「新規ページは必ず BaseLayout を使う」というルールを明文化しておくのがおすすめだ。

環境変数で測定 ID を管理する

本番とステージングで別の GA4 プロパティを使いたい場合は、測定 ID を環境変数に切り出すとよい。Astro では PUBLIC_ プレフィックスの環境変数がクライアントサイドで利用可能になる。

<script
  is:inline
  define:vars={{ measurementId: import.meta.env.PUBLIC_GA_MEASUREMENT_ID }}
>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', measurementId);
</script>

ただし define:varsis:inline の組み合わせには Astro のバージョンによって挙動差があるので、ビルド後の出力を必ず確認しよう。

まとめ

Astro サイトへの GA4 導入は、BaseLayout の <head> にスニペットを置くだけのシンプルな作業だが、is:inline を忘れるとバンドルされてしまい正しく動作しない。この一点さえ押さえれば、あとは普通の GA4 セットアップと同じだ。

関連記事

F/ この記事の設計を反映しているプロダクト: FlowAgent

see →
an

analytics note — editor

AI とデータ分析の実装ログを毎週編集。設計判断と運用のつまずきを、再現できる形で残すことを大切にしています。