# 機能設計書 112-Google Analytics

## 概要

本ドキュメントは、Next.jsの`@next/third-parties`パッケージが提供するGoogle Analytics最適化統合コンポーネントの設計を記載する。GoogleAnalyticsコンポーネントとsendGAEventヘルパー関数により、GA4（Google Analytics 4）の最適化されたスクリプト読み込みとイベント送信を実現する。

### 本機能の処理概要

**業務上の目的・背景**：Webサイトのアクセス解析はビジネス上の重要な要件であり、Google Analytics 4は最も広く使用されるアクセス解析ツールである。Next.jsアプリケーションにGA4を統合する際、パフォーマンスを損なわない最適化されたスクリプト読み込みが必要となる。本機能は`next/script`を活用し、GA4のスクリプト管理を最適化する。

**機能の利用シーン**：Next.jsアプリケーションにGoogle Analytics 4を導入する場面、ページビューの自動トラッキングを有効化する場面、カスタムイベントをGA4に送信する場面で利用される。

**主要な処理内容**：
1. GA4初期化スクリプトの挿入（dataLayer設定、gtag関数定義、config呼び出し）
2. gtag.jsスクリプトの最適化された読み込み（next/script経由）
3. カスタムイベント送信ヘルパー関数の提供（sendGAEvent）
4. Chrome Auroraチームへの機能利用シグナル送信（performance.mark）

**関連システム・外部連携**：Google Analytics 4（GA4）のgtag.jsスクリプト、Google Tag Managerのエンドポイント（`https://www.googletagmanager.com/gtag/js`）と連携する。

**権限による制御**：特に権限制御はない。GA4の測定IDが必要。

## 関連画面

本機能はコンポーネントとして任意の画面に配置可能であり、特定の画面に紐づかない。

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 任意のページ/レイアウト | 主機能 | GoogleAnalyticsコンポーネントの配置によるGA4トラッキング有効化 |

## 機能種別

外部サービス統合・データ連携

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| gaId | string | Yes | GA4の測定ID（G-XXXXXXX形式） | 空文字でないこと |
| dataLayerName | string | No | dataLayer変数名（デフォルト: 'dataLayer'） | - |
| debugMode | boolean | No | GA4デバッグモードの有効化 | - |
| nonce | string | No | Content Security Policy用のnonce値 | - |

### 入力データソース

- コンポーネントのprops（JSX属性として指定）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 初期化スクリプト | HTML script要素 | dataLayer初期化とgtag config呼び出し |
| gtag.jsスクリプト | HTML script要素 | Google Tag Managerからのgtag.js読み込み |

### 出力先

- DOM（ブラウザ上のscript要素として挿入）
- window.dataLayer（グローバル変数）

## 処理フロー

### 処理シーケンス

```
1. GoogleAnalyticsコンポーネントのマウント
   └─ dataLayerName変数の設定（モジュールレベル）
2. 初期化スクリプトの挿入
   └─ window[dataLayerName]の初期化、gtag関数定義、gtag('config', gaId)呼び出し
3. gtag.jsスクリプトの読み込み
   └─ next/Script経由でhttps://www.googletagmanager.com/gtag/js?id={gaId}を読み込み
4. useEffectで機能利用シグナル送信
   └─ performance.mark('mark_feature_usage', { detail: { feature: 'next-third-parties-ga' } })
5. カスタムイベント送信（任意）
   └─ sendGAEvent()でwindow[dataLayerName]にイベントをpush
```

### フローチャート

```mermaid
flowchart TD
    A[GoogleAnalytics マウント] --> B[dataLayerName設定]
    B --> C[初期化スクリプト挿入]
    C --> D[gtag.js読み込み]
    D --> E[GA4トラッキング開始]
    E --> F{カスタムイベント?}
    F -->|Yes| G[sendGAEvent呼び出し]
    G --> H[dataLayerにpush]
    F -->|No| I[自動ページビュー計測]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | dataLayerName固定 | 初回設定後、currDataLayerNameは変更されない | 複数回レンダリング時 |
| BR-02 | GA未初期化警告 | sendGAEvent呼び出し時にGAが未初期化の場合、console.warnを出力 | GA初期化前のイベント送信 |
| BR-03 | dataLayer不存在警告 | 指定されたdataLayer変数がwindowに存在しない場合、console.warnを出力 | dataLayer未定義時 |

### 計算ロジック

特になし。

## データベース操作仕様

本機能はデータベースを使用しない。

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | データベース操作なし |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | GA未初期化警告 | sendGAEvent呼び出し時にcurrDataLayerNameがundefined | console.warnで警告出力 |
| - | dataLayer不存在警告 | window[dataLayerName]が存在しない | console.warnで警告出力 |

### リトライ仕様

リトライ機能は実装されていない。スクリプト読み込み失敗時はnext/scriptの機能に委ねられる。

## トランザクション仕様

トランザクション管理は不要。

## パフォーマンス要件

- next/scriptによるスクリプト読み込み最適化（afterInteractive戦略がデフォルト）
- 初期化スクリプトとgtag.jsの2つのscript要素に分割し、並行読み込みを可能にする

## セキュリティ考慮事項

- nonce属性によるContent Security Policy（CSP）対応
- dangerouslySetInnerHTMLを使用しているが、入力値はpropsからのみ受け取る
- gaIdがスクリプト内にインラインで埋め込まれるため、XSSリスクに注意（propsの値を信頼する前提）

## 備考

- `'use client'`ディレクティブにより、Client Componentとして動作する
- performance.markはChrome Auroraチームの機能利用シグナルとして使用されている
- debugModeを有効にするとGA4のDebugView機能が利用可能になる

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | google.ts | `packages/third-parties/src/types/google.ts` | GAParams型の定義（gaId, dataLayerName, debugMode, nonce） |

**読解のコツ**: GAParams型は4つのプロパティを持ち、gaIdのみが必須。dataLayerNameのデフォルト値はコンポーネント側で'dataLayer'に設定される。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.tsx | `packages/third-parties/src/google/index.tsx` | パッケージのエクスポート構成を確認（GoogleAnalytics, sendGAEvent） |

**主要処理フロー**:
1. **4行目**: GoogleAnalyticsとsendGAEventをga.tsxからre-export

#### Step 3: メインコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ga.tsx | `packages/third-parties/src/google/ga.tsx` | GoogleAnalyticsコンポーネントとsendGAEvent関数の実装 |

**主要処理フロー**:
- **1行目**: `'use client'`ディレクティブ（Client Component）
- **14行目**: モジュールレベルの`currDataLayerName`変数（初回設定後は固定）
- **16-57行目**: GoogleAnalyticsコンポーネント（初期化スクリプト＋gtag.js読み込み）
- **38-49行目**: 初期化スクリプト（dataLayer設定、gtag関数定義、config呼び出し）
- **50-54行目**: gtag.jsの読み込み（next/Script経由）
- **59-72行目**: sendGAEvent関数（dataLayerへのイベントpush）

### プログラム呼び出し階層図

```
GoogleAnalytics (React Component)
    |
    +-- next/script (id="_next-ga-init")
    |       +-- window[dataLayerName] 初期化
    |       +-- gtag() 関数定義
    |       +-- gtag('config', gaId) 呼び出し
    |
    +-- next/script (id="_next-ga")
    |       +-- https://www.googletagmanager.com/gtag/js?id={gaId}
    |
    +-- useEffect
            +-- performance.mark('mark_feature_usage')

sendGAEvent(...args)
    +-- window[currDataLayerName].push(arguments)
```

### データフロー図

```
[入力]                     [処理]                          [出力]

gaId (props) -----------> GoogleAnalytics Component -----> <script> 要素 (DOM)
                               |                               |
                               +-- gtag('config', gaId) -----> Google Analytics サーバー
                               |
sendGAEvent(event) ------> window.dataLayer.push() -------> GA4 イベント送信
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ga.tsx | `packages/third-parties/src/google/ga.tsx` | ソース | GoogleAnalyticsコンポーネント・sendGAEvent関数 |
| google.ts | `packages/third-parties/src/types/google.ts` | ソース | GAParams型定義 |
| index.tsx | `packages/third-parties/src/google/index.tsx` | ソース | パッケージエクスポート |
| script.tsx | `packages/next/src/client/script.tsx` | ソース | next/scriptコンポーネント（依存先） |
