X Enterprises
Composables

Affiliate Impression

IntersectionObserver-based impression tracking — fires affiliate_impression to dataLayer when a buy button enters the viewport. Measure view-through conversion.

useAffiliateImpression

The useAffiliateImpression composable fires an affiliate_impression event to window.dataLayer the first time a buy button (or any CTA) enters the viewport. Without it, you only track clicks — you can't measure view-through conversion or rank merchants by exposure.

Usage

<script setup>
import { useAffiliateImpression } from '@xenterprises/nuxt-x-affiliate/app/composables/useAffiliateImpression'

const { el, impressed } = useAffiliateImpression({
  merchant: 'amazon',
  position: 'hero',
  label: 'Logitech K1',
  threshold: 0.5,        // 50% visible
})
</script>

<template>
  <XAFBuyButton ref="el" :link="mainLink" />
</template>

When the bound element scrolls into view (≥ 50% visible by default), the composable fires:

window.dataLayer.push({
  event: 'affiliate_impression',
  merchant: 'amazon',
  position: 'hero',
  label: 'Logitech K1',
})

Returns

KeyTypeDescription
elRef<HTMLElement | null>Template ref — bind to your CTA.
impressedRef<boolean>Reactive flag, true after the first impression fires.

Direct fire (no observer)

For programmatic use — e.g. firing from a non-Vue context, or tracking server-rendered content:

import { trackImpression } from '@xenterprises/nuxt-x-affiliate/app/composables/useAffiliateImpression'

trackImpression({
  merchant: 'amazon',
  position: 'sidebar',
  label: 'K1 keyboard',
  eventName: 'cta_view',  // custom event name (default: 'affiliate_impression')
})

API

FieldTypeDefaultDescription
merchantMerchantId'amazon'Merchant identifier.
positionstringPosition label for analytics (e.g. 'hero', 'sidebar', 'sticky').
labelstringProduct / CTA label.
eventNamestring'affiliate_impression'Custom GTM event name.
thresholdnumber0.5IntersectionObserver threshold (0–1).

Why it matters

Most affiliate sites measure the wrong thing. They track clicks and assume click-through rate = conversion rate. But:

  • A buy button that's seen by 10,000 visitors but clicked by 200 has 2% CTR — but those 200 are pre-qualified.
  • A buy button that's seen by 1,000 visitors but clicked by 50 has 5% CTR — better optimized, but less total revenue.

Without impressions, you can't distinguish "low-CTR merchant" from "low-impression merchant". With impressions, you can rank merchants by view-through conversion and double down on the right ones.

Pair with XAFStickyCTA

<XAFStickyCTA> already accepts a ref from useAffiliateImpression — wire them together to track sticky-CTA impressions:

<script setup>
const { el, impressed } = useAffiliateImpression({ merchant: 'amazon', position: 'sticky' })
</script>
<template>
  <XAFStickyCTA ref="el" :link="..." />
</template>

AI Context

composable: useAffiliateImpression
package: "@xenterprises/nuxt-x-affiliate"
use-when: >
  Tracking affiliate CTA visibility for view-through conversion analysis.
  Fires affiliate_impression to window.dataLayer when bound element
  enters the viewport (default 50% threshold). One impression per mount.
  Use as a template ref on XAFBuyButton, XAFStickyCTA, or any CTA element.
  Call trackImpression() directly for programmatic use without observer.
  Pair with click tracking from useAffiliateContent().trackClick() to
  measure impression-to-click conversion, not just click-through rate.
Copyright © 2026