RemixでGoogleAnalyticsを設定する

# はじめに

最近Remixを使ってアプリを作る機会がありました。その際に以前実装したGoogleAnalyticsの設定方法をど忘れしていたので、次から迷わないようにするために忘備録として残しておきます。

# TL;DR
詳しい実装方法については、こちらの公式リポジトリを確認していただけるとすぐに確認できます。

https://github.com/remix-run/examples/tree/main/google-analytics

# 環境変数を設定する

Google AnalayticsのトラッキングIDを環境変数に設定します。

:::note warn
今回は、トラッキングID自体の取得方法については割愛させていただきます。
:::

**.env**ファイルに、`GA_TRACKING_ID`を設定します。

トラッキングIDは、本番環境とステージング環境で異なる値を設定する必要があるため、環境変数を設定する際には、環境ごとに値を設定することをおすすめします。

```env
# STAGING
GA_TRACKING_ID="G-xxxxxxxxxx"
# PRODUCTION
# GA_TRACKING_ID="G-xxxxxxxxxx"
```

Fly.ioに環境変数をデプロイする際は次のコマンドを実行します。

```shell
/home/node/.fly/bin/flyctl secrets set GA_TRACKING_ID='G-xxxxxxxxxx' --app example-app
```

# gtags.client.tsを作成する

ページの遷移時やイベント発火時に、GoogleAnalyticsにイベントを送信するための関数を定義します。

クライアントでのみ利用可能とするため、ファイル名の末尾に`.client.ts`を付与することを忘れないでください。

このファイルの内容はこちらをコピーしていただくだけで大丈夫です。

https://github.com/remix-run/examples/blob/main/google-analytics/app/utils/gtags.client.ts

```gtags.client.ts
declare global {
  interface Window {
    gtag: (
      option: string,
      gaTrackingId: string,
      options: Record<string, unknown>
    ) => void;
  }
}

/**
 * @example
 * https://developers.google.com/analytics/devguides/collection/gtagjs/pages
 */
export const pageview = (url: string, trackingId: string) => {
  if (!window.gtag) {
    console.warn(
      "window.gtag is not defined. This could mean your google anylatics script has not loaded on the page yet."
    );
    return;
  }
  window.gtag("config", trackingId, {
    page_path: url,
  });
};

/**
 * @example
 * https://developers.google.com/analytics/devguides/collection/gtagjs/events
 */
export const event = ({
  action,
  category,
  label,
  value,
}: Record<string, string>) => {
  if (!window.gtag) {
    console.warn(
      "window.gtag is not defined. This could mean your google anylatics script has not loaded on the page yet."
    );
    return;
  }
  window.gtag("event", action, {
    event_category: category,
    event_label: label,
    value: value,
  });
};
```

これらの関数は、`window.gtag`を使用してGoogleAnalyticsにイベントを送信します。そのため、GoogleAnalyticsのスクリプトを読み込む必要があります。

```root.tsx
<>
    <script
      async
      src={`https://www.googletagmanager.com/gtag/js?id=${gaTrackingId}`}
    />
    <script
      async
      id="gtag-init"
      dangerouslySetInnerHTML={{
        __html: `
        window.dataLayer = window.dataLayer || [];
        function gtag(){dataLayer.push(arguments);}
        gtag('js', new Date());
        gtag('config', '${gaTrackingId}', {
          page_path: window.location.pathname,
        });
      `,
      }}
    />
</>
```

これらの内容は、後で説明する`App`コンポーネントにて、`dangerouslySetInnerHTML`を使用して実行します。

# loaderで、GA_TRACKING_IDを取得してクライアントに渡す

**root.tsx**に存在する`loader`にて、`process.env`から`GA_TRACKING_ID`を取得して、クライアントに渡します。

このとき、開発環境では、`GA_TRACKING_ID`を渡さないようにします。そのため、`process.env.NODE_ENV`を確認して、`GA_TRACKING_ID`を渡すかどうかを判断します。

```root.tsx
export async function loader({ request }: LoaderArgs) {
  const gaTrackingId = process.env.NODE_ENV !== "development" && process.env.NODE_ENV !== "test" ? process.env.GA_TRACKING_ID ?? "" : "";
  return json({
    gaTrackingId,
  });
}
```

# Appコンポーネントでページの遷移を記録する

**root.tsx**の`App`コンポーネントにて、`useLoaderData`を使用して、`loader`で取得した`GA_TRACKING_ID`を取得します。

この値が存在する場合のみ、GoogleAnalyticsのスクリプトを読み込み、`dangerouslySetInnerHTML`を使用して、`gtag.js`を実行します。

先ほど作成した`gtags.client.ts`から公開されている関数を使用して、GoogleAnalyticsにイベントを送信します。

ここでは、ページ遷移時に`pageview()`を実行するようにしています。

これにより、GoogleAnalyticsのダッシュボードで、ページ遷移時のデータを確認することができます。

```tsx
...
import * as gtag from "~/core/common/utils/gtags.client";

export default function App() {
  const { gaTrackingId } = useLoaderData<typeof loader>();
  const location = useLocation();

  useEffect(() => {
    if (gaTrackingId?.length) {
      gtag.pageview(location.pathname, gaTrackingId);
    }
  }, [location, gaTrackingId]);

  return (
    <html locale="en" className="h-full">
      <head>
        <Meta />
        <Links />
      </head>
      <body className="h-full">
      {!gaTrackingId ? null : (
          <>
            <script
              async
              src={`https://www.googletagmanager.com/gtag/js?id=${gaTrackingId}`}
            />
            <script
              async
              id="gtag-init"
              dangerouslySetInnerHTML={{
                __html: `
                window.dataLayer = window.dataLayer || [];
                function gtag(){dataLayer.push(arguments);}
                gtag('js', new Date());
                gtag('config', '${gaTrackingId}', {
                  page_path: window.location.pathname,
                });
              `,
              }}
            />
          </>
        )}
        <Outlet />
        <ScrollRestoration />
        <Scripts />
        <LiveReload />
      </body>
    </html>
  );
}
```

実際に動かしてみて、Google Analyticsのダッシュボード上で次のように表示されれば成功です。

![名称未設定のデザイン (57).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/9c22a3da-b1f3-297d-e811-3dc5fae65b11.png)

# 参考にした記事

https://github.com/remix-run/examples/tree/main/google-analytics