useAdTrack()
useAdTrack is the ad tracking wrapper. Each SwAd* component uses it to automatically report impressions / clicks with zero business code. You can also use it directly when rendering your own ad slot — it auto-assembles the two field layers ("slot-level fields slotKey / page from component props + creative-level fields id / creativeId / adType from item data") into the reporting payload, so you never hand-build it.
Reporting goes through
useTrackerunderneath, which auto no-ops when the SDK isn't configured.
Parameters
useAdTrack(options) — options carries the slot-level tracking fields:
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
slotKey | string | ✓ | — | Ad slot key → tracking ad_slot_key |
slotName | string | '' | Ad slot name → ad_slot_name | |
pageKey | string | '' | Page key → page_key | |
pageName | string | '' | Page name → page_name | |
adType | AdType | '' | Default ad type (item.adType takes precedence) → ad_type |
Return Value
| Name | Type | Description |
|---|---|---|
reportImpression | (items: SwAdItem[]) => void | Report one impression (does nothing when items is empty) |
reportClick | (item: SwAdItem) => void | Report one click |
reportClose | (items: SwAdItem[], reason: 'close' | 'skip') => void | Report close / skip (adClose with close_reason in payload; no-op on empty array). Components with close buttons are pre-wired (SwAdSplash / SwAdPopup / SwAdPause); the preroll "skip" button is rendered by your slot — call reportClose(items, 'skip') in your skip handler; natural countdown completion is not reported |
observeImpression | (el, getItems, onVisible?) => () => void | Bind impression detection; returns a cleanup function |
observeImpression(el, getItems, onVisible?)
Uses IntersectionObserver (threshold: 0.5) to watch el entering the viewport. On first entry it calls reportImpression(getItems()) and the optional onVisible callback, then disconnects (dedup — reported only once).
el: HTMLElement— the root element to observegetItems: () => SwAdItem[]— returns the currently shown ad items (lazy — captures data at impression time)onVisible?: (items) => void— extra callback after impression- Returns
() => void— cleanup (call on unmount). Returns a no-op under SSR / environments withoutIntersectionObserver
Usage Examples
// Example 1: wire impression + click tracking into a custom ad slot
const rootRef = ref<HTMLElement>()
const { reportClick, observeImpression } = useAdTrack({
slotKey: 'home_banner',
pageKey: 'home',
})
onMounted(() => {
const stop = observeImpression(rootRef.value!, () => props.items)
onUnmounted(stop)
})
function onClick(item: SwAdItem) {
reportClick(item)
}
// Example 2: report impression manually (non-IntersectionObserver case)
const { reportImpression } = useAdTrack({ slotKey: 'splash', adType: 'splash' })
reportImpression(visibleAds.value)
Caveats
- Prefer
SwAd*components — they bundleuseAdTrack+IntersectionObserver, so you don't wire tracking yourself. Use this composable directly only for custom ad slots. - Don't hand-assemble payloads on the business side — slot-/creative-level field mapping is centralized here; hand-building risks missing or misnaming fields.
- Impression dedup: a given
elreports only once per viewport entry (reportedflag +disconnect).
Related
useTracker— underlying unified reporting entry- Ad & Tracking —
SwAd*component family + full tracking fields