# 機能設計書 113-Google Tag Manager

## 概要

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

### 本機能の処理概要

**業務上の目的・背景**：Google Tag Managerはマーケティングタグ・アクセス解析タグの一元管理ツールであり、多くのWebサイトで利用されている。Next.jsアプリケーションにGTMを統合する際、パフォーマンスへの影響を最小限に抑えつつ、タグ管理の柔軟性を確保する必要がある。本機能はnext/scriptを活用し、GTMスクリプトの最適化された読み込みを提供する。

**機能の利用シーン**：Next.jsアプリケーションにGoogle Tag Managerを導入する場面、dataLayerを通じたカスタムイベント送信を行う場面、GTMのプレビュー・認証機能を利用する場面で使用される。

**主要な処理内容**：
1. GTM初期化スクリプトの挿入（dataLayer初期化、gtm.startイベント設定）
2. gtm.jsスクリプトの最適化された読み込み（カスタムURL対応、認証・プレビュー対応）
3. カスタムイベント送信ヘルパー関数の提供（sendGTMEvent）
4. Chrome Auroraチームへの機能利用シグナル送信（performance.mark）

**関連システム・外部連携**：Google Tag Manager（gtm.js）、カスタムGTMスクリプトURL（gtmScriptUrl）と連携する。

**権限による制御**：GTMのauth・previewパラメータにより、環境制御（本番・ステージング・プレビュー）が可能。

## 関連画面

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

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

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| gtmId | string | Yes* | GTMコンテナID（GTM-XXXXXXX形式） | gtmIdまたはgtmScriptUrlのいずれかが必須 |
| gtmScriptUrl | string | No* | カスタムGTMスクリプトURL | gtmIdまたはgtmScriptUrlのいずれかが必須 |
| dataLayerName | string | No | dataLayer変数名（デフォルト: 'dataLayer'） | - |
| auth | string | No | GTM環境認証トークン | - |
| preview | string | No | GTMプレビュー環境ID | - |
| dataLayer | Record<string, JSONValue> | No | 初期dataLayerデータ | - |
| nonce | string | No | CSP用nonce値 | - |

### 入力データソース

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

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 初期化スクリプト | HTML script要素 | dataLayer初期化とgtm.startイベント設定 |
| gtm.jsスクリプト | HTML script要素 | GTMスクリプトの読み込み |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. GoogleTagManagerコンポーネントのマウント
   └─ currDataLayerNameの更新
2. スクリプトURLの構築
   └─ gtmScriptUrlまたはデフォルトURL + id, l, gtm_auth, gtm_preview, gtm_cookies_winパラメータ
3. 初期化スクリプトの挿入
   └─ window[dataLayerName]の初期化、gtm.startイベントpush、初期dataLayerのpush
4. gtm.jsスクリプトの読み込み
   └─ next/Script経由で構築したURLからスクリプトを読み込み
5. useEffectで機能利用シグナル送信
   └─ performance.mark('mark_feature_usage', { detail: { feature: 'next-third-parties-gtm' } })
```

### フローチャート

```mermaid
flowchart TD
    A[GoogleTagManager マウント] --> B[スクリプトURL構築]
    B --> C{gtmId指定?}
    C -->|Yes| D[URLにid追加]
    C -->|No| E[カスタムURL使用]
    D --> F{auth指定?}
    E --> F
    F -->|Yes| G[gtm_authパラメータ追加]
    F -->|No| H{preview指定?}
    G --> H
    H -->|Yes| I[gtm_preview + gtm_cookies_win追加]
    H -->|No| J[初期化スクリプト挿入]
    I --> J
    J --> K[gtm.js読み込み]
    K --> L[GTMタグ管理開始]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | dataLayerName更新 | currDataLayerNameは毎回レンダリング時に更新される（GAとは異なる） | コンポーネントレンダリング時 |
| BR-02 | カスタムdataLayerName | dataLayerNameが'dataLayer'以外の場合、URLにlパラメータが追加される | dataLayerName変更時 |
| BR-03 | preview時のcookies_win | preview指定時にgtm_cookies_win=xが自動追加される | preview使用時 |
| BR-04 | 事前イベントキューイング | sendGTMEventはGTM初期化前でもwindow[dataLayer]にイベントをキューイングできる | GTM初期化前のイベント送信 |

### 計算ロジック

特になし。

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

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | URL構築エラー | gtmScriptUrlが無効なURL | URLコンストラクタがスロー |

### リトライ仕様

リトライ機能は実装されていない。

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

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

## パフォーマンス要件

- next/scriptによるスクリプト読み込み最適化
- data-ntpc="GTM"属性によるパフォーマンス計測識別

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

- nonce属性によるCSP対応
- auth/previewパラメータによるGTM環境制御
- dangerouslySetInnerHTMLを使用（propsからの信頼された入力のみ）
- dataLayerの初期データはJSON.stringifyでシリアライズされる

## 備考

- `'use client'`ディレクティブによりClient Componentとして動作
- sendGTMEventはdataLayerNameパラメータでカスタムdataLayer名を指定可能
- GTM初期化前にsendGTMEventを呼んでもwindow[dataLayer]が自動作成されキューイングされる

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | google.ts | `packages/third-parties/src/types/google.ts` | GTMParams型の定義（Union型: GTMParamsWithId | GTMParamsWithScriptUrl） |

**読解のコツ**: GTMParamsはUnion型で、gtmIdまたはgtmScriptUrlのいずれかが必須となる設計。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | gtm.tsx | `packages/third-parties/src/google/gtm.tsx` | GoogleTagManagerコンポーネントとsendGTMEvent関数 |

**主要処理フロー**:
- **1行目**: `'use client'`ディレクティブ
- **8行目**: モジュールレベルの`currDataLayerName`（デフォルト'dataLayer'）
- **10-75行目**: GoogleTagManagerコンポーネント
- **23-38行目**: スクリプトURL構築（URLSearchParams使用）
- **55-66行目**: 初期化スクリプト（IIFE、dataLayer初期化、初期データpush）
- **67-72行目**: gtm.jsスクリプト読み込み（data-ntpc="GTM"属性付き）
- **77-83行目**: sendGTMEvent関数（window[dataLayer]へのpush）

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

```
GoogleTagManager (React Component)
    |
    +-- URL構築 (new URL + searchParams)
    |       +-- id, l, gtm_auth, gtm_preview, gtm_cookies_win
    |
    +-- next/script (id="_next-gtm-init")
    |       +-- dataLayer初期化
    |       +-- gtm.startイベント
    |       +-- 初期dataLayerデータ
    |
    +-- next/script (id="_next-gtm")
    |       +-- gtm.jsスクリプト読み込み
    |
    +-- useEffect
            +-- performance.mark('mark_feature_usage')

sendGTMEvent(data, dataLayerName?)
    +-- window[dataLayer] = window[dataLayer] || []
    +-- window[dataLayer].push(data)
```

### データフロー図

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

gtmId / gtmScriptUrl ----> URL構築 -----> script要素 -------> GTM スクリプト読み込み
auth / preview ---------> URLパラメータ                          |
dataLayer (初期データ) ---> JSON.stringify -> script内埋め込み -> dataLayer初期化
                                                                 |
sendGTMEvent(data) ------> window[dataLayer].push() ----------> GTMイベント配信
```

### 関連ファイル一覧

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