SwAdPreroll

Ad Placement Four Essentials

  • Use case: the pre-roll phase before video playback — placed into the #preroll-ad slot of SwVideoPlayer / SwVideoFeed; countdown / skip / release belong to the player's phase state machine, this component only owns content and tracking
  • Industry form: IAB in-stream pre-roll (AdSDK v0.0.1 has no matching format yet; ad_type uses the framework extension value preroll)
  • Visual form: single image direct render / multi-image carousel inside the pre-roll layer, fit=contain (player's black background pads the sides), compliance "Ad" badge on by default
  • Tracking events: adImpression (reported on mount — the pre-roll layer is necessarily fullscreen-visible, no IntersectionObserver) / adClick; 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.

SwAdPreroll is the pre-roll video ad component. Like SwAdBanner it is an image-type self-rendering component (single item direct, multiple via SwCarousel), with two pre-roll-specific differences: impression reports immediately on mount (the layer is gated by the player = necessarily visible), and images default to contain.

Copy + CTA overlay (opt-in): when an item carries any of title / description / cta / advertiser, a "headline + sub-copy + CTA button" overlay renders over the creative image (like a real ad); pass only image to keep it image-only. The CTA is a button-styled <span> (the whole ad is already a link; clicks go to link).

Multi-image carousel inside a 16:9 mock player

加载中...

Multi-image carousel (autoplayDelay)

加载中...

fit: contain vs cover

加载中...

Inside SwVideoPlayer #preroll-ad (real home)

加载中...

Impression on mount (vs IO-based)

加载中...

Standard Usage (with the player's pre-roll phase)

<script setup lang="ts">
const { data: r } = await useFetch('/movie/detail/1')
// Legacy play_ads protocol ({ id, name, content, link }) normalized in one line
const items = computed(() => playAdsToSwAdItems(r.value?.play_ads))
</script>

<template>
  <SwVideoPlayer
    :links="r.play_links"
    :preroll-ad="items.length > 0"
    :preroll-ad-duration="+r.play_ads_time"
    :preroll-ad-auto-close="r.play_ads_auto_jump === 'y'"
  >
    <template #preroll-ad="{ skip }">
      <!-- @empty: release straight into the content when ad data is broken -->
      <SwAdPreroll :items="items" slot-key="player_preroll" page-key="movie" @empty="skip()" />
    </template>
  </SwVideoPlayer>
</template>

The ads.app_info_player_preroll slot of system/info shares the same shape as play_ads — normalize with the same playAdsToSwAdItems().

Props

NameTypeRequiredDefaultDescription
itemsSwAdItem[]✓—Ad creatives (normalize play_ads protocol via playAdsToSwAdItems first)
slotKeystring✓—Slot key → tracking ad_slot_key
slotNamestringundefinedSlot name → ad_slot_name
pageKeystringundefinedPage key → page_key
pageNamestringundefinedPage name → page_name
fit'contain' | 'cover' | 'fill''contain'Image fit (contain shows the full creative; player's black bg pads)
showAdLabelbooleanundefinedCompliance "Ad" badge (recommended on for pre-rolls); when not set it follows the global swiftConfig.ad.showLabel (default true)
autoplaybooleantrueAuto-rotate when multiple items
autoplayDelaynumber3000Carousel interval (ms)

Events

NamePayloadDescription
load—Ad filled and ready
empty—No fill (wire to skip() to release into content)
impressionitems: SwAdItem[]Impression (auto-tracking already sent; for extra business use)
clickitem: SwAdItemCreative clicked (auto-tracking already sent)

playAdsToSwAdItems

Legacy play_ads protocol normalizer (auto-imported):

playAdsToSwAdItems(playAds: PlayAdProtocolItem[] | null | undefined): SwAdItem[]
// Mapping: id→id(String) / name→name / content(image)→image / link→link
// null / undefined / non-array → [] (pair with @empty)

Creative Overlay Tokens (--sw-ad-overlay-*)

The title / description / CTA overlay on the creative is rendered by the internal AdOverlay — SwAdPopup / SwAdSplash share the exact same knobs:

VariableDefaultDescription
--sw-ad-overlay-gradientlinear-gradient(to top, rgb(0 0 0 / 72%), rgb(0 0 0 / 0%))Bottom gradient scrim over the creative (keeps text readable)
--sw-ad-overlay-title-colorrgb(255 255 255)Title text color
--sw-ad-overlay-desc-colorrgb(255 255 255 / 88%)Description text color
--sw-ad-overlay-advertiser-colorrgb(255 255 255 / 75%)Advertiser name text color
--sw-ad-overlay-cta-bgvar(--primary)CTA button background
--sw-ad-overlay-cta-colorvar(--primary-foreground)CTA button text color
--sw-ad-overlay-pb1remBottom padding of the creative (tune it to clear safe areas / the ad label)

Caveats

  • Impression timing differs from other SwAd*: banner etc. report on viewport entry via IntersectionObserver; this component reports on mount — never place it in regular page layouts (it would report impressions while invisible); use SwAdBanner there.
  • Countdown / skip button / auto-release are the player phase's responsibility (prerollAdDuration / prerollAdAutoClose / slot-scope skip()), not duplicated here.
  • Video-based pre-roll creative (video instead of image) is reserved for v2, pending real demand.

See Also