questionnaire docs
Tracking

Session Tracking

Event-driven placement session tracking with instant ad KV reporting and focus gating.

Session Tracking

Placement-based session tracking that monitors user engagement and ad fill values with instant event-driven API reporting.

Entry: components/layout/SessionTracker.js

Flow

Heartbeat payload

{
  "session_id": "sess_...",
  "campaign_id": "23985256456",
  "ad_group_id": "197961067837",
  "placement": "xyz.com",
  "landing_path": "/some-article",
  "kv_ads": {
    "display-ad-1": { "kv_value": 20 },
    "display-ad-2": { "kv_value": 22.5 }
  },
  "duration": 45,
  "current_path": "/current-path",
  "is_heartbeat": true
}

Key files

FilePurpose
lib/utils/sessionTracking.jsLifecycle, heartbeat, visibility
lib/utils/sessionApi.jsAPI requests and payloads
lib/utils/sessionHelpers.jslocalStorage, country, device
lib/utils/sessionPlacement.jsPlacement type normalization
lib/utils/sessionConstants.jsKeys and endpoints
components/layout/SessionTracker.jsClient component in root layout

Placement normalization

Only website subdomains are reduced to the base domain. All other Google Ads placement types are sent unchanged.

TypeExampleSent to API
Website subdomainblog.site.comsite.com
Website domainsite.comUnchanged
Mobile app (modern)mobileapp::2-com.example.appUnchanged
Mobile app (iOS)mobileapp::1-123456789Unchanged
Mobile app (legacy AFM)1.android.com.foo.bar.adsenseformobileapps.comUnchanged
Mobile app (legacy AFM)com.foo.bar.adsenseformobileapps.comUnchanged
Mobile app categorymobileappcategory::69500Unchanged
Android packagecom.example.appUnchanged
YouTube channelyoutube.com::L8ZULXASCc1I_oaOT0NaOQUnchanged
YouTube videoyoutube.com/video/wtLJPvx7-ysUnchanged
Other / non-hostmyappUnchanged

Behavior

FeatureDetail
Heartbeat intervalEvent-driven (Instant payload on session creation, ad arrival, and exit ping; no recurring 5s/10s pings)
Background pauseTracking & immediate API pings only execute when document is visible AND window is focused
Exit pingpagehide + beforeunload with keepalive: true
Display ad trackingRecorded on slotRenderEnded. Refreshed impressions generate unique keys (slot_r1, slot_r2) so auto-refreshed ads are preserved and never overwritten
Interstitial ad trackingRecorded on slotVisibilityChanged when displayed on screen (inViewPercentage > 0). Preloaded background interstitials are ignored to match GAM impressions 1:1
Rewarded ad trackingRecorded on onAdReceived after user clicks CTA button and views ad — triggers immediate API ping
Domain gatingRuns on every domain (no allowlist)
PlacementSubdomains reduced to base domain before API send

On this page