🥽

Google Analyticsを導入した

2024年07月03日


このブログにGoogle Analyticsを入れてみた。

こちらのサイトによると、 @astrojs/partytownを使うことで、 Google AnalyticsのスクリプトをWebWorkerで動かせるらしい。 結果的にパフォーマンススコアが上がるらしい。

この辺のパフォーマンススコアとかよくわかってない。 コンシューマー向けのWEB技術の知識をつけねば。

1. Google Analyticsにプロパティを追加

どうやら、Google Analyticsでは、監視対象のサイトごとに プロパティ というものを作るらしい。 名前から想像するものとだいぶ違うけど、そういう文化なんだろう。

2. @astrojs/partytown 導入

Terminal window
npm i -D @astrojs/partytown
astro.config.mjs
import { defineConfig } from 'astro/config';
import partytown from '@astrojs/partytown';
// https://astro.build/config
export 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 も入れた。(この辺は公式ドキュメント参照。なくても良いらしいけど念の為。)

GoogleAnalytics.astro
---
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>

このコンポーネントを使う側は、以下のような感じ。

BaseLayout.astro
---
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だけでカスタムコンポーネントを作る仕組みがあったり、最近のフレームワークの進化はすごい。