定義
ボタンクリック・決済開始・ログイン成功などの プロダクト意図 を分析ツールに送るとき、画面コードが Google タグマネージャー(GTM)・PostHog などの ベンダー SDK を直接呼ばず、useTelemetry().track(...) のような 単一 API だけを使う設計である。
ファサード(facade) は、複雑な配管の前に置く単純な窓口である。ファンアウト(fan-out) は、1 回の track 呼び出しが複数の シンク(sink) — データを受け取るシステム — に複製されることである。
なぜ必要か
コールサイトごとに posthog.capture と dataLayer.push を混在させると、(1) 片方のシンクにだけイベントが行き、(2) シンクを差し替えるときにアプリ全体を直す必要があり、(3) SDK 例外が決済・ログインフローを壊す可能性がある。ファサードは 消費側は意図だけを伝え、init・ルーティング・マスキングは Provider が所有 する。
動作原理
TelemetryProviderがシンクを初期化し、コンテキストでアクションを提供する。track({ event, ...props })→ 1 次シンク(例: dataLayer)へ push → ルールに合うイベントだけ 2 次シンク(例: PostHog)へルーティング。identify(userId, traits)/reset()でログイン・ログアウト境界を揃える。- シンクごとに 独立した env ゲート(キーがなければそのシンクだけ no-op)。
- すべてのシンク呼び出しは try/catch best-effort — 分析失敗がビジネスロジックを止めない。
実務での適用
- 新規イベントはフック経由のみとするよう、コードレビュー・lint(ベンダー SDK import 禁止リスト)。
- autocapture を切り、明示的 track だけを使うとノイズ・上限を制御しやすい。
- セッションリプレイを使う場合、入力・画像など マスキングのデフォルト を init に置く。
- export だけされて消費側が 0 のヘルパーは デッドパス — 文書に Non-goal として書き、移植時に蘇生させない。
トレードオフ
| 選択 | 利点 | コスト |
|---|---|---|
| 単一ファサード | 到達の一貫性・差し替え容易 | Provider 設計・テストが必要 |
| コールサイト直接 SDK | 短期は速い | ドリフト・例外伝播 |
| best-effort で握りつぶし | UX 保護 | 失敗が静か — ダッシュボードのスモークが必要 |
使うべきでない場合
- サーバー監査ログ・決済台帳のように 欠損が許されない 記録(クライアント分析層に任せないこと)。
- 個人情報を props に載せて複数シンクへ無差別複製する場合(スキーマ・マスキングを先に)。
よくある失敗
capturePostHogとtrackを混用 → GTM 未到達。- ログアウトで
resetを抜き、前ユーザーのセッションが続く。 - テストで分析 mock が throw するのに try/catch がなく決済テストが赤になる。
関連概念
- react-context-render-granularity — Provider でアクションを注入するときのレンダー範囲