useExposure()

useExposure provides the generic "element entered the viewport once" timing primitive: it attaches an IntersectionObserver (default visibility ratio ≥ 0.5) to the target element, invokes the callback once on first entry, then stops observing automatically (one exposure per element).

It only handles timing — what happens inside the callback is entirely up to you: report via useTracker, call your own tracking SDK, or run pure UI logic (lazy loading / animation triggers). Internally, ad impressions (useAdTrack) and SwLink's :track.exposure are built on it.

Safe no-op in SSR / environments without IntersectionObserver (returns an empty cleanup).

Parameters

useExposure(el, onExposed, options?)

NameTypeRequiredDefaultDescription
elHTMLElement✓—Target element to observe
onExposed() => void✓—Callback on first viewport entry (fires once)
options.thresholdnumber0.5Visibility ratio threshold

Return value

() => void — cleanup function: stops observing manually (call on unmount; idempotent no-op once fired).

Examples

One-shot on enter viewport

加载中...

threshold 0.1 vs 0.9

加载中...

List exposure counting (tracking)

加载中...
// Example 1: content card exposure reporting (with useTracker)
const cardRef = ref<HTMLElement>()
let stop = () => {}
onMounted(() => {
  stop = useExposure(cardRef.value!, () => {
    useTracker().track('appPageitemExposure', { item_id: '123', item_type: 'video', /* … */ })
  })
})
onBeforeUnmount(() => stop())

// Example 2: your own tracking SDK (escape hatch — anything inside the callback)
onMounted(() => {
  useExposure(bannerRef.value!, () => myOwnSdk.report('banner_seen'))
})

// Example 3: custom threshold (a tall card counts at 20% visibility)
onMounted(() => {
  useExposure(listItemRef.value!, onSeen, { threshold: 0.2 })
})

Notes

  • Fires once per element: it auto-disconnects after firing; with DOM reuse (virtual scrolling), call again to re-arm exposure.
  • Prefer SwLink :track for content cards: card-link scenarios get exposure + click tracking built in (powered by this composable).
  • Call inside onMounted (a real DOM element is required); invoke the returned cleanup on unmount.
  • SwLink — built-in exposure tracking via :track.exposure
  • useAdTrack — ad impressions (reuses this composable internally)
  • useTracker — unified WebSDK reporting entry