SwAdPause

Ad Placement Four Essentials

  • Use case: a dismissible ad shown when the video is paused (the CTV / streaming prime slot — the user has actively stopped, attention on the screen). Rendered into SwVideoPlayer's #pause-ad slot, slotKey e.g. play_pause
  • Industry form: Pause Ad / Pause Screen Ad (AdSDK format pause)
  • Visual form: centered / corner card + dismissible ✕; no hard fullscreen block — the paused frame stays partly visible, and clicking the picture outside the card resumes playback and closes it
  • Tracking events: adImpression (reported on display) / adClick / close; built-in zero-config, silent no-op when the tracker gate is off

Picking the wrong scenario = wrong ad_type / timing in tracking. See Ad Component Selection.

SwAdPause is the pause ad slot component — a "player-scenario" self-rendering component of the ad foundation. Triggering and gating are handled by the player: once SwVideoPlayer has pause-ad enabled, the user pauses → the player's built-in gating (debounce delay / filtering out system pauses / eligibility / mutual exclusion with the paywall) all passes → the #pause-ad slot shows. This component only owns the creative + frequency capping + tracking: mounting equals a "valid pause moment"; per useAdFrequency capping it decides whether to show, and on a hit it renders the creative card + impression tracking.

⚠️ Strictly distinct from the paywall #paywall: the paywall = monetization / not closable / hard fullscreen block / triggered when the trial ends; this component = advertising / closable / doesn't block resume / triggered on pause.

Props

NameTypeRequiredDefaultDescription
itemsSwAdItem[]✓—Ad creatives (uses the first item; image required, optional title / cta / link)
slotKeystring✓—Ad slot key → ad_slot_key
slotNamestringundefinedAd slot name → ad_slot_name
pageKeystringundefinedPage key → page_key
pageNamestringundefinedPage name → page_name
ratiostring'16/9'Creative aspect ratio
frequencyAdFrequencyStrategy'session'Frequency strategy ('session' once per session / 'always' every pause / 'Nm'·'Nh'·'Nd' once every N minutes·hours·days)
frequencyKeystringundefinedFrequency storage key (defaults to slotKey)
closablebooleantrueShow the close ✕
showAdLabelbooleanundefined"Ad" compliance badge; when not set it follows the global swiftConfig.ad.showLabel (default true — recommended on for pause ads)

Events

NamePayloadDescription
empty—First item has no image, or frequency not hit (does not render)
impressionitems: SwAdItem[]Impression (reported on display, auto tracking)
clickitem: SwAdItemCreative clicked (auto tracking)
close—Close ✕ clicked (wire the slot's close to dismiss the player overlay)

Usage (rendered into the player's #pause-ad slot)

SwAdPause is not used standalone — you place it into SwVideoPlayer's #pause-ad slot; the slot scope { close } is used to close it:

<SwVideoPlayer :url="videoUrl" type="m3u8" pause-ad @pause-ad="onPauseExposure">
  <template #pause-ad="{ close }">
    <SwAdPause :items="pauseAds" slot-key="play_pause" @close="close" />
  </template>
</SwVideoPlayer>

<!-- Knobs: ratio — creative aspect ratio; frequency — capping (use 0 while debugging = pop on every pause);
     frequency-key — explicit capping storage key (defaults to slot-key; change the key on release to reset capping);
     closable=false — hide the ✕ (dismiss only by clicking outside the card to resume);
     show-ad-label follows the global ad.showLabel when not set (default true — the "Ad" compliance badge, keep it on) -->
<SwAdPause
  :items="pauseAds"
  slot-key="play_pause"
  ratio="16/9"
  frequency="always"
  frequency-key="play-pause-v2"
  :closable="false"
  @close="close"
/>

<script setup>
const pauseAds = [
  { id: 'pa-1', image: '/ad/pause.jpg', title: '50% off membership', cta: 'Subscribe now', link: '/vip' },
]
function onPauseExposure() {
  // Player-level "valid pause moment" hook (independent of the component's adImpression)
}
</script>

Frequency capping

frequency reuses useAdFrequency:

  • 'session' (default): pops once per session.
  • N (number): pops once every N days.
  • 0: pops on every valid pause (no capping).

Finer controls ("N times per session / minute-level cooldown") will be added once a real consumer calibrates them; v1 does not introduce them (YAGNI).

Closing & resuming

  • Click ✕: emit('close'); wire the slot's close() to dismiss the overlay; the video stays paused (no auto-resume).
  • Click the picture outside the card: the overlay wrapper is pointer-events:none, so the click passes through to the picture and resumes playback → the player's video:play auto-dismisses the pause ad (closes on resume).
  • Frequency not hit: emit('empty') renders nothing; the transparent overlay doesn't block clicks, so resume works as usual.

Style Tokens

These CSS variables can be overridden on your side (the fallback is the default):

VariableDefaultDescription
--sw-ad-pause-card-bgrgb(17 17 20 / 96%)Creative card background
--sw-ad-pause-card-shadow0 8px 32px rgb(0 0 0 / 45%)Creative card shadow
--sw-ad-pause-title-colorrgb(255 255 255 / 92%)Title text color
--sw-ad-pause-cta-bgvar(--primary)CTA button background (a brand gradient works too)
--sw-ad-pause-cta-colorrgb(255 255 255)CTA button text color
--sw-ad-pause-close-bgrgb(0 0 0 / 45%)Close button background
--sw-ad-pause-close-colorrgb(255 255 255)Close button icon color

Caveats

  • Gating is the player's job: debounce delay, filtering out system pauses (dragging / buffering / backgrounding / pre-roll phase / completion), eligibility, and mutual exclusion with the paywall are all built into SwVideoPlayer; this component treats mounting as a valid pause moment — see SwVideoPlayer · Pause Ad.
  • Doesn't block resume controls: the creative card is centered and the area outside it is clickable to resume playback — don't make the card a fullscreen mask.
  • Tracking is built in (ad_type=pause) and gated twice by the tracker.
  • Demo note: this component renders into the player's slot and depends on the player's pause state to trigger, so a standalone demo wouldn't be representative; for a runnable demo see the SwVideoPlayer pause-ad scenario (PauseAdDemo — pause-triggered, closes on resume; hence, per docs convention, no separate DemoBox here).