ブログに戻る

Astroサイトにプライバシーファーストのアナリティクスを追加する

AstroのView Transitionsは標準のアナリティクススクリプトを静かに壊します。クッキーや同意バナーなしで、すべてのルート変更を計測する正しいパターンをご紹介します。

AstroのView Transitionsは、ブラウザの完全リロードなしにページコンテンツをその場で入れ替えます。つまりDOMContentLoadedloadに依存するアナリティクススクリプトは、最初の訪問時に一度だけ発火することになります。その後のクライアントサイドナビゲーションはすべて見えません。これは設定ミスではなく、ClientRouterの動作仕様による根本的な帰結です。

同じサイレントトラッキングの問題はSvelteKit 2やRemixにも存在しますが、各フレームワークでの修正方法は異なります。Astroでの答えはastro:page-loadライフサイクルイベントです。

通常のscriptタグが失敗する理由

<ClientRouter />が有効な場合(Astro 4ではastro:transitionsからのオプトイン、Astro 5ではデフォルト有効)、ナビゲーションはページをアンロードしません。Astroは次のページをバックグラウンドでフェッチし、DOMを入れ替え、URLを更新します。現在のJavaScriptコンテキストを破壊することなくすべてを行います。

素の<script>タグで読み込まれたトラッカースクリプトは、Astroのビルドパイプラインではバンドルされたモジュールスクリプトとして扱われます。バンドルされたモジュールスクリプトは、ページセッションごとに正確に一度だけ実行されます。トラッカーは初期化し、ランディングページのページビューを発火し、その後ユーザーがナビゲートしても二度と実行されません。

ナビゲーションごとに発火させるには、初期化ロジックをAstroのナビゲーションライフサイクルに接続する必要があります。正しいフックはastro:page-loadで、新しいページが表示され、すべてのブロッキングスクリプトが読み込まれた後に発火します。最初のロードでも、その後のすべての遷移でも発火します。

正しい統合方法

ルートレイアウト(src/layouts/Layout.astroまたは同等のもの)にトラッカースクリプトを一度追加し、astro:page-loadのリスナーをアタッチします。

---
// Layout.astro
---
<html lang="en">
  <head>
    <!-- your head content -->
  </head>
  <body>
    <slot />

    <script
      is:inline
      src="https://api.monoid.website/tracker.min.js"
      data-site-id="YOUR_SITE_ID"
      async
    ></script>
  </body>
</html>

is:inlineディレクティブは、Astroのバンドラーにこのスクリプトをそのまま残すよう指示します。これがないとAstroはスクリプトをモジュールとして処理し、重複排除し、再実行を抑制します。is:inlineがあれば、scriptタグはすべてのページのHTML出力にそのまま埋め込まれます。

View Transitionsを使用しないサイトでは、これだけで十分です。トラッカーはロード時に一度発火し、それで完了です。

View Transitionsナビゲーションの取り扱い

サイトが<ClientRouter />を使用している場合、トラッカーの組み込みhistory.pushStateフックが各遷移の後に正しく発火します。トラッカーは内部的にAstroのナビゲーションイベントをリッスンします。追加の設定は不要です。

確認するには、DevToolsのNetworkタブを開き、collectでフィルターしてください。2つのページ間をナビゲートします。最初のロードを含め、ナビゲーションごとに1つのPOSTリクエストが見えるはずです。

トラッカーを条件付きで注入していて、各スワップ後に再初期化が必要な場合(例えば動的アイランドのマウント後)、手動で再実行をトリガーできます。

<script data-astro-rerun>
  // This block re-executes after every View Transition.
  // Use sparingly — most tracker logic should not live here.
  if (window.__monoid) {
    window.__monoid.trackPageview();
  }
</script>

data-astro-rerun属性は、すべての遷移後にインラインスクリプトを再実行させます。これはis:inlineを含意するため、バンドルされていないスクリプトにのみ適用される点に注意してください。

環境の分離

Astroプロジェクトは通常、ローカル開発、プレビュー、本番の各環境を持ちます。環境変数でsite_idを保持し、開発時はトラッキングを抑制します。

---
const siteId = import.meta.env.PUBLIC_MONOID_SITE_ID
---

{siteId && (
  <script
    is:inline
    src="https://api.monoid.website/tracker.min.js"
    data-site-id={siteId}
    async
  ></script>
)}

本番では.envPUBLIC_MONOID_SITE_IDを設定し、ローカルでは未設定のままにします。AstroはPUBLIC_接頭辞を持つ変数をクライアントに公開します。接頭辞のないサーバー専用変数はブラウザで実行されるコードからは見えません。

不要なもの

クッキー同意バナーは不要。CMP統合も不要。コレクションエンドポイントは、IPアドレス、User-Agent、サーバー側のシークレット、そして現在の日付から日次の訪問者ハッシュを計算します。

visitor_hash = SHA-256(IP + UA + SALT_SECRET + YYYY-MM-DD)

ハッシュは24時間ごとにリセットされます。訪問者の端末には何も保存されません。大まかなブラウザファミリーと端末タイプは、集計レポート用にリクエストのUser-Agentからサーバー側で導出されます。完全なUser-Agent文字列、ブラウザバージョン、永続識別子が保存されることはありません。

Astroサイトは多くの場合、完全に静的またはエッジレンダリングで、JavaScriptは最小限です。クッキーも同意要件もない2 KB未満のアナリティクススクリプトを追加することは、その哲学に自然になじみます。メンテナンスするnpmパッケージも、更新するSDKも、アナリティクス処理のためにGDPRの法的根拠を文書化する必要もありません。