# TD Web SDK統合

このガイドでは、Webサイトへの**TD Web SDK**（`td-web-sdk`）のインストール方法とIn-Browser Messaging向けの設定方法を説明します。Engage Studioでキャンペーンを作成する前にこのセットアップを完了してください。

このページの対象読者
このページはWebサイトにSDKを組み込む**Webデベロッパー**向けです。キャンペーンを作成するマーケターは、セットアップが完了したら[Popupキャンペーンの作成](/ja/products/marketing-cloud/engage-studio/experiences/create-a-popup-campaign)または[Inlineキャンペーンの作成](/ja/products/marketing-cloud/engage-studio/experiences/create-an-inline-campaign)に進んでください。

## ステップ 1 — SDKのインストール

プロジェクトに合ったインストール方法を選択してください。

CDN（推奨）
すべてのページの`<head>`に非同期ローダースニペットを追加します。最も手軽に始められ、あらゆる技術スタックで動作します。

```html
<head>
  <!-- TD Web SDK非同期ローダー -->
  <script type="text/javascript">
  !function(t,e){if(void 0===e[t]){e[t]=function(){e[t].clients.push(this),this._init=[Array.prototype.slice.call(arguments)]},e[t].clients=[];for(var r=function(t){return function(){return this["_"+t]=this["_"+t]||[],this["_"+t].push(Array.prototype.slice.call(arguments)),this}},s=["set","trackEvent","trackPageview","trackClicks","addRecord","setSignedMode","setAnonymousMode","blockEvents","unblockEvents","fetchGlobalID","fetchServerCookie","fetchUserSegments","fetchPersonalization","resetUUID","collectTags","ready"],c=0;c<s.length;c++){var o=s[c];e[t].prototype[o]=r(o)}var n=document.createElement("script");n.type="text/javascript",n.async=!0,n.src="https://cdn.treasuredata.com/sdk/web/1.0/td-sdk.min.js";var i=document.getElementsByTagName("script")[0];i.parentNode.insertBefore(n,i)}}("Treasure",this);
  </script>
</head>
```

CDNのバージョン管理
パス `/sdk/web/1.0/` はマイナーバージョンに固定されます。パッチリリースはスニペットを更新せずに自動的に反映されます。

npm
モジュールバンドラー（webpack、Vite、Rollupなど）を使用するプロジェクトはnpmでインストールします。

```bash
npm install td-web-sdk
```

```typescript
// TypeScript / ESモジュール
import Treasure from 'td-web-sdk'

// CommonJS
const Treasure = require('td-web-sdk').default
```

## ステップ 2 — SDKの初期化

`Treasure`インスタンスを1つ作成し、参照を保持してください。`trackEvent`の呼び出しより前に、できるだけ早く初期化してください。

```javascript
const td = new Treasure({
  writeKey: 'YOUR_WRITE_KEY',   // TDアカウントの書き込み専用APIキー
  database: 'YOUR_DATABASE',    // ターゲットデータベース名
  host: 'YOUR_REGION_HOST',     // 下記のリージョン別ホストを参照
})
```

### In-Browser Messaging（パーソナライズ）の有効化

Engage Studioからポップアップまたはインラインメッセージを受け取るには、`personalization`オプションを追加します。設定すると、`trackEvent`の呼び出しが標準のインジェストエンドポイントではなく**RT Personalization API**経由にルーティングされ、SDKがキャンペーンペイロードを取得してメッセージを自動的にレンダリングします。

```javascript
const td = new Treasure({
  writeKey: 'YOUR_WRITE_KEY',
  database: 'YOUR_DATABASE',
  host: 'YOUR_REGION_HOST',
  personalization: {
    endpoint: 'YOUR_P13N_ENDPOINT',  // リージョン依存。CSMに確認してください。
    token: 'YOUR_WP13N_TOKEN',       // Audience StudioのWP13n-Token
  },
})
```

パーソナライズはインジェストを置き換えます
`personalization`を設定すると、**イベントはTDデータベースに書き込まれず**、RT Personalization APIに送信されます。インジェストとパーソナライズの両方が必要な場合は、デュアルパスパターンについてカスタマーサクセスマネージャーにご相談ください。

### 設定リファレンス

| **オプション**  | **必須**  | **説明**  |
|  --- | --- | --- |
| `writeKey` | ✅ | 書き込み専用APIキー。TDアカウント設定で確認できます。 |
| `database` | ✅ | イベントを保存するターゲットデータベース名。 |
| `host`
 | —
 | データインジェストエンドポイント。リージョンに応じて以下の値を指定してください。
| リージョン | ホスト |
|  --- | --- |
| US | `us01.records.in.treasuredata.com` |
| Tokyo | `ap01.records.in.treasuredata.com` |
| AP02 | `ap02.records.in.treasuredata.com` |
| EU01 | `eu01.records.in.treasuredata.com` |

 |
| `personalization.endpoint` | ✅（In-Browser Messagingを使用する場合） | RT Personalization APIエンドポイント。リージョン依存。 |
| `personalization.token` | ✅（In-Browser Messagingを使用する場合） | Audience StudioのPersonalization設定にあるWP13n-Token。 |
| `startInSignedMode` | — | `true` に設定すると、最初のイベントからPII（クライアントID、IPアドレス）を収集します。デフォルト: `false`（匿名モード）。 |
| `logging` | — | デバッグ用のSDKコンソールログを有効化します。デフォルト: 開発環境では `true`。 |


## ステップ 3 — ページビューの計測

すべてのページロードまたはSPAのルート変更で、`event_name: 'page_view'` を指定して `trackEvent` を呼び出します。RT PersonalizationがEntry Criteriaを評価してメッセージを配信するために必要です。

Static HTML / MPA
すべてのページロードで `trackEvent` を呼び出します。ナビゲーションのたびにページが再読み込みされるため、1ページにつき1回の呼び出しで十分です。

```html
<script>
  // SDK初期化後
  td.trackEvent('events', { event_name: 'page_view' })
</script>
```

React SPA
クライアントサイドのルート変更では、ルートを監視する `useEffect` 内で `trackEvent` を呼び出します。ただし、**最初のレンダーはスキップ**して初回ロード時の二重カウントを防いでください。

```jsx
// components/Layout.jsx
import { useEffect, useRef } from 'react'
import { useLocation } from 'react-router-dom'

export default function Layout({ children }) {
  const location = useLocation()
  const firstRender = useRef(true)

  useEffect(() => {
    if (firstRender.current) {
      firstRender.current = false
      return // スキップ: 初回はロード時に計測済み
    }
    window.td?.trackEvent('events', { event_name: 'page_view' })
  }, [location.pathname, location.search])

  return <>{children}</>
}
```

Next.js (App Router)
`usePathname` と `useSearchParams` を監視する `PageviewTracker` クライアントコンポーネントを追加します。静的エクスポートでは `<Suspense>` でラップが必要です。

```jsx
// components/PageviewTracker.jsx
'use client'
import { useEffect, useRef } from 'react'
import { usePathname, useSearchParams } from 'next/navigation'

export default function PageviewTracker() {
  const pathname = usePathname()
  const searchParams = useSearchParams()
  const firstRender = useRef(true)

  useEffect(() => {
    if (firstRender.current) {
      firstRender.current = false
      return // スキップ: 初回はロード時に計測済み
    }
    window.td?.trackEvent('events', { event_name: 'page_view' })
  }, [pathname, searchParams])

  return null
}

// app/layout.jsx
import { Suspense } from 'react'
import PageviewTracker from '@/components/PageviewTracker'

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <Suspense fallback={null}>
          <PageviewTracker />
        </Suspense>
        {children}
      </body>
    </html>
  )
}
```

GTM
Google Tag Managerで、**All Pages**と**History Change**（SPA向け）で発火する**Custom HTML**タグを作成します。

```html
<!-- GTM Custom HTMLタグ -->
<script>
  if (window.td) {
    window.td.trackEvent('events', { event_name: 'page_view' })
  }
</script>
```

MPAサイトでは**All Pages**トリガーを設定し、シングルページアプリケーションには**History Change**トリガーを追加してください。

## ステップ 4 — ユーザーIDの設定

SDKには匿名IDの管理メカニズムが2つあります。**サーバーサイドCookie（`td_ssc_id`）の使用を推奨します**。お客様自身のサーバーから発行され、JavaScriptが設定するファーストパーティCookieを7日間に制限するブラウザのITP制限を受けないためです。

### オプション A — サーバーサイドCookie（推奨）

`td_ssc_id` はブラウザではなくお客様のサーバーが設定するCookieです。Safari ITPやiOS環境でも確実に持続し、In-Browser Messagingにおける推奨識別子です。

**事前のインフラ設定が必要です**: お客様のドメイン上に小さなSSCサーバーエンドポイントをデプロイする必要があります（例: `ssc.yourdomain.com`）。SSCサーバーのセットアップガイドについてはカスタマーサクセスマネージャーまたは実装チームにお問い合わせください。

SSCインフラが整ったら：

```javascript
const td = new Treasure({
  writeKey: 'YOUR_WRITE_KEY',
  database: 'YOUR_DATABASE',
  host: 'YOUR_REGION_HOST',
  useServerSideCookie: true,
  sscDomain: 'yourdomain.com',   // ルートドメイン
  personalization: {
    endpoint: 'YOUR_P13N_ENDPOINT',
    token: 'YOUR_WP13N_TOKEN',
  },
})

// Signedモードを有効化してからサーバーサイドCookieを取得
td.setSignedMode()
td.fetchServerCookie(
  (sscId) => console.log('SSC ID:', sscId),
  (error) => console.error('SSC fetch failed:', error)
)
```

`fetchServerCookie` が成功すると、`td_ssc_id` がその後のすべてのイベントに自動的に含まれます。

SSCの前提条件
`fetchServerCookie` には以下が必要です。

1. SDKの設定で `useServerSideCookie: true`
2. `fetchServerCookie()` の前に `setSignedMode()` を呼び出すこと
3. お客様のドメインにSSCサーバーエンドポイントがデプロイ済みでアクセス可能であること


### オプション B — ファーストパーティブラウザCookie（フォールバック）

SSCインフラがまだ用意できない場合、SDKは `td_client_id`（ブラウザが設定するファーストパーティCookie）にフォールバックします。サーバーインフラなしで動作しますが、ITP制限（Safari/iOSでは7日間の上限）の影響を受けます。

```javascript
// 追加設定不要 — td_client_idは自動管理される
const td = new Treasure({
  writeKey: 'YOUR_WRITE_KEY',
  database: 'YOUR_DATABASE',
  host: 'YOUR_REGION_HOST',
  personalization: {
    endpoint: 'YOUR_P13N_ENDPOINT',
    token: 'YOUR_WP13N_TOKEN',
  },
})
```

| **識別子**  | **設定者**  | **ITP / Safari**  | **インフラ**  | **推奨度**  |
|  --- | --- | --- | --- | --- |
| `td_ssc_id` | お客様のサーバー | ✅ 影響なし | SSCサーバーが必要 | **推奨** |
| `td_client_id` | ブラウザ（JS） | ⚠️ 7日間の上限 | 不要 | フォールバックのみ |


### 認証済みユーザーIDの設定

ユーザーがログインした後は、どのCookieを使用していても、デバイスやチャネルをまたいでイベントを紐付けるために内部ユーザーIDを設定してください。

```javascript
// ログイン後 / セッション復元後
td.set('$global', 'td_user_id', 'YOUR_INTERNAL_USER_ID')

// この時点以降、すべてのイベントにtd_user_idが含まれます
td.trackEvent('events', { event_name: 'page_view' })
```

ID設計について
メールアドレスや電話番号ではなく、**安定した非PII内部ID**（アカウントID、CRM IDなど）を使用してください。ユーザーが認証済みの場合のみ `td_user_id` を設定してください。

### 匿名モードとSignedモード

デフォルトではSDKは**匿名モード**で動作し、識別子とIPアドレスは送信されません。ユーザーがトラッキングに同意した場合にSignedモードを有効化してください。

```javascript
// ユーザーが同意 — PII収集を有効化（SSCには必須）
td.setSignedMode()

// ユーザーが同意を撤回
td.setAnonymousMode()

// すべてのイベントをブロック（例: Cookieバナーで拒否）
td.blockEvents()
td.unblockEvents() // 再開
```

## ステップ 5 — セットアップの確認

ブラウザのDevToolsを開き → **Network**タブで`host`または`personalization.endpoint`ドメインへのリクエストをフィルタリングします。`trackEvent`を呼び出した後、以下が確認できるはずです。

- **パーソナライズなし**: インジェストエンドポイントへのPOSTリクエスト（イベントペイロード付き）。
- **パーソナライズあり**: p13nエンドポイントへのPOSTリクエスト。レスポンスの`offers`オブジェクトにアクティブなキャンペーンペイロードが含まれます。


**Console**タブでも確認できます。SDKはリクエストURLとペイロードを `[td-debug]` メッセージとして出力します。

## ユーザーIDとプライバシー

### 匿名から認証済みへの遷移

```
ユーザーが訪問（ログインなし）
  └─ td_ssc_idがサーバーから発行される（推奨）
     または td_client_idがブラウザによって設定される（フォールバック）
  └─ イベントは匿名で送信される

ユーザーがログイン
  └─ td.set('$global', 'td_user_id', 'user_12345')
  └─ 以降のイベントにCookie IDとtd_user_idの両方が含まれる
  └─ RT 2.0のIDスティッチングが匿名履歴とユーザーを紐付ける
```

### 自動収集されるプロパティ

SDKはすべてのイベントに以下のフィールドを自動的に付加します。実装は不要です。

| **プロパティ**  | **説明**  | **PII?**  |
|  --- | --- | --- |
| `td_ssc_id` | サーバーサイドCookieの識別子（推奨 — ITP制限なし） | あり（Signedモードのみ） |
| `td_client_id` | ファーストパーティブラウザCookieの識別子（フォールバック — SafariでITP 7日間の上限あり） | あり（Signedモードのみ） |
| `td_session_id` | セッションごとのUUID（将来のSDKバージョン） | なし |
| `td_url` | 現在のページURL | 場合による |
| `td_path` | URLパス（例: `/product/123`） | なし |
| `td_host` | ホスト名 | なし |
| `td_referrer` | 参照元URL | 場合による |
| `td_title` | ページタイトル | なし |
| `td_viewport` | ブラウザウィンドウサイズ（`幅x高さ`） | なし |
| `td_screen` | 画面解像度（`幅x高さ`） | なし |
| `td_language` | ブラウザの言語設定 | なし |
| `td_user_agent` | ブラウザのUser-Agent文字列 | 場合による |
| `td_version` | SDKバージョン | なし |


## 次のステップ

- [イベントトラッキング](/ja/products/marketing-cloud/engage-studio/experiences/event-tracking) — `view_item`、`add_to_cart`、`purchase`などのビジネスイベントを定義する
- [Popupキャンペーンの作成](/ja/products/marketing-cloud/engage-studio/experiences/create-a-popup-campaign)
- [Inlineキャンペーンの作成](/ja/products/marketing-cloud/engage-studio/experiences/create-an-inline-campaign)