このブログにGoogle Analyticsを入れてみた。
こちらのサイトによると、 @astrojs/partytownを使うことで、 Google AnalyticsのスクリプトをWebWorkerで動かせるらしい。 結果的にパフォーマンススコアが上がるらしい。
この辺のパフォーマンススコアとかよくわかってない。 コンシューマー向けのWEB技術の知識をつけねば。
1. Google Analyticsにプロパティを追加
どうやら、Google Analyticsでは、監視対象のサイトごとに プロパティ というものを作るらしい。 名前から想像するものとだいぶ違うけど、そういう文化なんだろう。
2. @astrojs/partytown 導入
npm i -D @astrojs/partytown
import { defineConfig } from 'astro/config';import partytown from '@astrojs/partytown';
// https://astro.build/configexport default defineConfig({ integrations: [ partytown({ config: { forward: ['dataLayer.push'], }, }), ],});
3. headにGoogle Analyticsのタグを埋め込み
ここが一番苦戦した。
Google Analyticsでは、プロパティごとに「トラッキングID」というものが付与され、 タグ内にトラッキングIDが埋め込まれることで、プロパティを識別している模様。
<!-- Google tag (gtag.js) --><script async src="https://www.googletagmanager.com/gtag/js?id=トラッキングID"></script><script> window.dataLayer = window.dataLayer || []; function gtag() { dataLayer.push(arguments); } gtag('js', new Date());
gtag('config', 'トラッキングID');</script>
このトラッキングIDは、秘匿情報(Gitにコミットしちゃいけない情報)なのでは?というのと、 ローカル環境で試しているときにはこのタグ自体を無効化しないといけないのでは?ということで、 以下のような仕様にしたかった。
- トラッキングIDはベタ書きせずに、環境変数から読み込む
- トラッキングIDが指定されていなければ、Google Analyticsのタグを追加しない
こうすることで、以下のような挙動になるはず。
- デプロイ時は、Cloudflare Pagesの環境変数設定で指定する → タグが追加される
- ローカルでの確認時は設定されない → タグが追加されない
Astroには、環境変数を読み込む仕組みがあるため、
それを使えば環境変数からの読み込みはできるものの、astroコンポーネント内に記載した <script>
タグの内部に読み込んだ変数をレンダリングするのがうまく行かず。
Astroでは <script>
タグは特別扱いされているようで、通常の変数埋込みの {変数名}
みたいなやり方ではダメだった。
結果的に、 data-*
経由で渡すというなんとも不格好な感じになってしまった。
また、@astrojs/partytownに処理してもらうために type="text/partytown"
も追加して、
Astro側の最適化を抑制するために is:inline
も入れた。(この辺は公式ドキュメント参照。なくても良いらしいけど念の為。)
---interface Props { trackingId: string;}
const { trackingId } = Astro.props;---
<script is:inline type="text/partytown" src={`https://www.googletagmanager.com/gtag/js?id=${trackingId}`}></script>
<!-- data属性経由でトラッキングIDを渡す。JSで要素を取得しやすいように、idも設定。 --><script is:inline type="text/partytown" id="ga" data-ga-tracking-id={trackingId}> // data属性からトラッキングIDを取得 const trackingId = document.getElementById('ga').dataset.gaTrackingId; window.dataLayer = window.dataLayer || []; function gtag() { window.dataLayer.push(arguments); } gtag('js', new Date()); gtag('config', trackingId);</script>
このコンポーネントを使う側は、以下のような感じ。
---import GoogleAnalytics from '../components/GoogleAnalytics.astro';
// 環境変数からトラッキングIDを取得const trackingId = import.meta.env.GA_TRACKING_ID;---
<html lang="ja"> <head> <meta charset="utf-8" /> <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> <meta name="viewport" content="width=device-width" /> <meta name="generator" content={Astro.generator} /> <title>タイトル</title> <!-- トラッキングIDがあれば、GoogleAnalyticsのタグを埋め込む --> {trackingId && <GoogleAnalytics trackingId={trackingId} />} </head> <!-- 省略 --></html>
ちなみに、これをコンポーネントを分けずに書こうとしたところ、Prettierのエラーがどうしても解消できず、 泣く泣くコンポーネントを分けることにした。まあ結果的に見通しは良くなったからいいものの、解せない。。
終わりに
なんとなくハマったものの、なんとかやりたかったことは実現できた。 調査のためにAstroのドキュメントを見ていることで、色々発見があって良い。 Astroだけでカスタムコンポーネントを作る仕組みがあったり、最近のフレームワークの進化はすごい。