X Enterprises

nuxt-x-affiliate

The everything-layer for niche affiliate review sites — 89 XAF* review-site components + 10 dashboard-family components, full-coverage schema.org JSON-LD composables (BlogPosting, Product + Review + AggregateRating, FAQ, Breadcrumb, Organization, Person, WebSite), FTC + opt-in legal disclosures, GTM click + impression tracking, site chrome + engagement loops + conversion widgets. Plug-and-play for 100 sites.

nuxt-x-affiliate

The everything-layer for niche affiliate review sites. 99 XAF* components under the same prefix (10 dashboard family + 89 review-site family), schema.org JSON-LD composables (Product, Review, FAQ, Breadcrumb, Organization, Person, WebSite, Article, HowTo, Recipe), FTC + opt-in legal disclosures, GTM click + impression tracking, site chrome + engagement loops + conversion widgets, and a full merchant tagging API. A consuming site provides the data; every block on the page is wired.

Breaking (next minor after v0.6.0, 2026-07): the dashboard family moved from app/components/X/AF/ to app/components/XAF/ — all 99 components now live flat in one folder. Auto-import names (XAFBanner, XAFDashboard, …) are unchanged, so template usage is unaffected. Only consumers deep-importing component file paths (e.g. import XAFDashboard from '@xenterprises/nuxt-x-affiliate/app/components/X/AF/Dashboard.vue') need to update the path to app/components/XAF/Dashboard.vue.

Also breaking (same minor): useConsentTracking() is renamed to useXAFConsentTracking() (plugin consent-tracking.client.tsxaf-consent-tracking.client.ts) to resolve the auto-import collision with nuxt-x-marketing's identically-named composable when a site extends both layers. Behavior, the xAffiliate.consent storage key, and the xAffiliate.tracking config are unchanged — update call sites to the new name.

Latest (v0.6.0, 2026-06-29): <XAFContentCard> and <XAFPageHero> ship first-class image support (image / imageAlt / imageAspect / imageLoading props) — no more per-site forks for card thumbnails and photo heroes. No breaking changes. Full release notes →

Previous (v0.5.0, 2026-06-28): Consent-aware cookie banner rewritten on Nuxt UI v4 primitives (UModal, UToggle, UButton, UBadge) with banner + preferences modal in one. New useConsentTracking() composable dynamically injects GTM / GA4 / Clarity / Meta Pixel / Hotjar / custom scripts only after the matching consent category is granted. Storage moved cookie → localStorage to align with nuxt-x-marketing. New xAffiliate.tracking.scripts[] escape hatch. 181/181 tests, 0 typecheck errors. No breaking changes. Full release notes →

Previous (v0.4.1, 2026-06-28): Multi-language support out of the box. New <XAFLocaleProvider> (cookie persistence + window event + <html lang>/dir + optional built-in switcher) + useXafLocale() composable. Default 9-locale list (en, es, fr, de, pt, it, ja, zh, ar) with RTL support. 159/159 tests, 0 typecheck errors. No breaking changes.

Previous (v0.3.5, 2026-06-28): 5 new components (<XAFPagination>, <XAFSearchFilters>, <XAFTaxonomyArchive>, <XAFCurrencySwitcher>, <XAFPageHero>, <XAFPageSection>) + 1 composable (useXafExperiment()). Typecheck gate enforced in CI and prepublishOnly. 47 pre-existing strict-mode typecheck errors swept. Nuxt 4 config plumbing fixes (multi-export composables, defu-merge-safe defaults). 89 components total (78 → 89).

Two component families under the same package, both flat in app/components/XAF/:

  • XAF* dashboard family (10 components) — for running your own affiliate program.
  • XAF* review-site family (89 components) — for being an affiliate of networks like Amazon and Walmart. Covers every block from a product hero through FAQ through sticky CTA through decision quiz, plus site chrome (header/footer/mega menu/404) and engagement loops (polls/quizzes/comments), pagination, faceted filters, taxonomy archives, currency switching, and A/B testing hooks. Auto-imported; plug-and-play.

Installation

npm install @xenterprises/nuxt-x-affiliate

Peer requirements: nuxt ^4.2.1 and @nuxt/ui ^4.9.0.

// nuxt.config.ts
export default defineNuxtConfig({
  extends: [['@xenterprises/nuxt-x-affiliate', { install: true }]],
})

What the consumer writes

The batteries are included — the layer ships default pages (/affiliate, /affiliate/dashboard), 99 auto-imported components, and every composable. The ideal consumer writes three things:

  1. extends in nuxt.config.ts (above).
  2. app/app.config.ts — it must live in the consuming project's app/ directory (Nuxt 4 srcDir convention); at the project root your overrides are silently ignored and only Nuxt UI defaults survive. Site identity, legal base URL, tracking IDs, and merchant tags:
// app/app.config.ts
export default defineAppConfig({
  xAffiliate: {
    // Canonical legal pages live centrally — every site points here.
    legal: {
      baseUrl: 'https://x.enterprises/legal',
      optIn: {
        health: false,            // → enables <XAFHealthDisclaimer>
        aiContent: true,          // → enables <XAFAIContentDisclosure>
        sponsoredContent: false,  // → enables <XAFSponsoredContentDisclosure>
      },
    },
    brand: {
      name: 'BestKitchenGear.com',        // required — layer default is undefined
      url: 'https://bestkitchengear.com', // required — layer default is undefined
      tagline: 'We test so you don\'t have to.',
      logo: 'https://bestkitchengear.com/logo.png',
      ogImage: 'https://bestkitchengear.com/og.png',
    },
    author: {
      name: 'Jane Reviewer', // E-E-A-T — drives <XAFAuthorBox> + Person schema
      role: 'Senior Kitchen Gear Editor',
    },
    tracking: {
      gtmId: 'GTM-XXXXXXX', // scripts fire only after consent (via <XAFCookieConsent>)
    },
  },
  xAffiliateContent: {
    merchants: {
      // Sites MUST set their own tag per merchant — untagged links
      // silently break commission attribution.
      amazon:  { tagValue: 'yourtag-20' },
      walmart: { tagValue: 'your-walmart-id' },
    },
  },
})
  1. Environment variables — none. This layer reads no env vars; all configuration is through app/app.config.ts.

Everything else is opt-out or override: drop <XAF*> components into your pages, call the schema composables per page, and replace any default page via Nuxt's standard page overriding (your file at the same path wins) — or disable a default page entirely via the xAffiliate.pages switches (the route then renders a 404):

export default defineAppConfig({
  xAffiliate: {
    pages: {
      landing: true,    // /affiliate
      dashboard: false, // /affiliate/dashboard → 404
    },
  },
})

The layer ships no default homepage — review sites compose their own from the XAF* family (XAFHero, XAFContentIndex, …). Dashboard-family defaults (landing hero, benefits, signup strings) can be overridden under the same xAffiliate namespace:

export default defineAppConfig({
  xAffiliate: {
    referralParam: 'ref',
    referralBaseUrl: 'https://yoursite.com',
    cookieDays: 30,
    currency: 'USD',
    shareMessage: 'Check this out!',
  },
})

What the Layer Provides

Dashboard family (XAF*)

Components (auto-imported):

  • XAFBanner — Promotional hero banner with CTA and variant styling (gradient / primary / dark)
  • XAFCommissionTiers — Commission tier display with current-tier highlight and progress bar
  • XAFDashboard — Full affiliate dashboard composing all sub-components
  • XAFLeaderboard — Top affiliates ranking with earnings and referral counts
  • XAFPayoutHistory — Payout history table with status badges
  • XAFReferralLink — Referral link with copy-to-clipboard
  • XAFReferralTable — Referral tracking table (source, status, commission, date)
  • XAFShareButtons — Social sharing buttons (Twitter, Facebook, LinkedIn, Email)
  • XAFSignupForm — Affiliate application form with configurable fields
  • XAFStatsCards — Stats overview cards (clicks, conversions, earnings, pending)

Review-site family (XAF*) — 89 components

SEO + E-E-A-T:

  • XAFBreadcrumbs — BreadcrumbList schema, accessible nav
  • XAFAuthorBox — Author bio with credentials + social (E-E-A-T)
  • XAFContributors — Multi-author byline (tester + writer + editor + photographer)
  • XAFByline — Minimal byline ("By Jane, Tom, and Sam") with dates + read time
  • XAFVerdict — TL;DR / verdict callout (featured-snippet gold)
  • XAFFAQ — FAQ list + FAQPage schema
  • XAFLastUpdated — "Updated {date}" freshness badge
  • XAFReadingTime — "{n} min read" badge (auto-computed from content)
  • XAFPriceVerified — "Price verified {date}" trust badge
  • XAFPressLogos — "As seen in" media logos (E-E-A-T)
  • XAFExpertQuote — Quoted experts with credentials + link

Data / structured content:

  • XAFSpecsTable — Spec sheet with optional grouping
  • XAFComparisonTable — vs-competitors with "Our pick" highlight
  • XAFScoreBreakdown — Sub-scores with weighted average + total
  • XAFDecisionMatrix — Multi-criteria weighted scoring matrix
  • XAFCalloutBox — info / success / warning / danger / tip
  • XAFQuote — Pull-quote with optional source
  • XAFKeyTakeaways — Bulleted key-points list
  • XAFTableOfContents — Auto-generated from article headings, scrollspy active highlight
  • XAFMethodology — "How we test" editorial disclosure
  • XAFSurveyResults — Survey data with bar visualization
  • XAFCustomerReviews — User-submitted reviews with rating distribution
  • XAFStatHighlight — Big-number statistic card with optional icon, context, and trend

Commerce:

  • XAFHero — Product hero (image + title + rating + price + CTA)
  • XAFProductCard — Product card for grids
  • XAFReviewCard — Review summary card for lists
  • XAFStickyCTA — Floating buy button appears when original scrolls out
  • XAFStarRating — Half-star ratings, 4 color variants
  • XAFBuyButton — The moneymaker — image, price, CTA, disclosure, tagging, click + impression tracking
  • XAFAffiliateLink — Slot-based link when you need full visual control
  • XAFProsCons — 1- or 2-column pros/cons, auto-collapse
  • XAFBestFor — "Best for X" badge (3 variants)
  • XAFDealAlert — Email-me-when-price-drops signup
  • XAFWaitlist — Email-me-when-back-in-stock signup
  • XAFBundle — Bundle of two or more products with savings label and total
  • XAFCountdown — Live countdown timer for limited-time offers with auto-expiry handling
  • XAFOfferBanner — Dismissible site-wide promo / info / warning / success banner
  • XAFShippingBar — Free-shipping progress bar ("Add $X more to qualify")

Legal:

  • XAFDisclosure — FTC disclosure in 4 variants
  • XAFArticleDisclosure — FTC 16 CFR §255.5 in-content snippet
  • XAFAIContentDisclosure — AI-assisted content notice (opt-in via legal.optIn.aiContent)
  • XAFSponsoredContentDisclosure — Paid sponsorship notice (opt-in via legal.optIn.sponsoredContent)
  • XAFHealthDisclaimer — Not-medical-advice notice (opt-in via legal.optIn.health)
  • XAFCookieConsentConsent-aware GDPR / CCPA banner with category-level preferences + auto-tracking injection (GTM / GA4 / Clarity / Meta Pixel / Hotjar / etc.) from xAffiliate.tracking

Social / growth:

  • XAFNewsletter — Email capture with submit event + privacy link
  • XAFExitIntent — Exit-intent popup with email capture + cookie dismissal
  • XAFSocialProof — "Trending", "Bought today" signals
  • XAFTestimonials — Reader testimonial grid
  • XAFShareReview — Share to Twitter / FB / LinkedIn / Reddit / WhatsApp / Email / Copy link
  • XAFPrintButton — Print-friendly export
  • XAFReactions — "Helpful / Not helpful" buttons
  • XAFSearchBar — Site search with combobox + keyboard nav
  • XAFNewsletterArchive — Past newsletter issues list (date, subject, excerpt, product count)
  • XAFRssFeedLink — Head-only RSS auto-discovery <link> tag (renders nothing visible)

Reader engagement / page chrome:

  • XAFReadingProgress — Top progress bar with reading % ARIA
  • XAFBackToTop — Floating back-to-top button (appears after scroll threshold)
  • XAFQuickActions — Floating side menu (save / share / copy / print / report)
  • XAFTagChips — Clickable tag chips at end of article
  • XAFContentCard — Review or article card with meta, optional rating, price line, and CTA
  • XAFAskQuestion — Reader-submitted question form with optional email
  • XAFCommentForm — Comment form with optional email and threaded replies
  • XAFCommentList — Threaded comment list with reply / upvote actions
  • XAFPoll — Single-question poll with optional pre-vote results
  • XAFQuiz — Multi-step product recommendation quiz with progress bar
  • XAFDecisionFlow — Interactive flowchart quiz that lands on a recommended product
  • XAFNotFound — Friendly 404 page (or any status code) with status code, CTA, and inline search
  • XAFPageHero — Full-viewport hero for landing / category pages with eyebrow, title, actions slot
  • XAFPageSection — Bounded-width section wrapper with bg / padding / id props
  • XAFContentIndex — Listing-page section composing XAFContentCard grids/lists with hero header, empty state, and "View all" link
  • XAFDateDisplay — Locale-aware <time> element for ISO dates (long / short / numeric / relative presets, UTC-pinned for SSR)

Schema-specific:

  • XAFHowTo — HowTo schema + numbered steps UI
  • XAFRecipe — Recipe schema + recipe card with ingredients + nutrition

Media:

  • XAFVideoEmbed — YouTube / Vimeo embed
  • XAFGallery — Image gallery (grid / carousel / masonry) + optional lightbox
  • XAFRelatedProducts — "You might also like" section
  • XAFCompareSlider — Before/after image compare slider (horizontal / vertical)

Composables:

  • useAffiliate() — SSR-safe state for affiliate program data
  • useReferralTracking() — Detects and persists referral codes via URL params and cookies
  • useAffiliateContent() — Review-site API: merchant config, idempotent link tagging, price formatting, click tracking
  • useAffiliateImpression() / trackImpression() — IntersectionObserver-based impression tracking (fires affiliate_impression to dataLayer when buy button enters viewport)
  • useSchema() — Multi-export schema.org JSON-LD composable:
    • useOrganizationSchema() — site-wide Organization
    • usePersonSchema() — author Person (E-E-A-T)
    • useProductSchema() — Product + Review + AggregateRating + Offer (drives Google star SERPs)
    • useFAQSchema() — FAQPage
    • useBreadcrumbSchema() — BreadcrumbList
    • useWebSiteSchema() — WebSite + optional SearchAction (sitelinks searchbox)
    • useArticleSchema() — Article with publisher
    • useSiteMeta() — title / description / OG / Twitter Card / canonical / robots
    • cleanSchema() — strips undefined/empty values
  • useXAFConsentTracking() — Consent-aware script injection (GTM / GA4 / Clarity / custom) gated on <XAFCookieConsent> categories
  • useXafLocale() — Multi-locale state (cookie persistence, <html lang>/dir, RTL support) behind <XAFLocaleProvider>
  • useXafExperiment() — Sticky A/B test variant assignment with exposure tracking
  • useXAFContentQuery() — Paginated content query state manager, plus typed wrappers useXAFReviews() / useXAFArticles() / useXAFCategories() / useXAFSearch()
  • useXafDateFormat() — Locale-aware date formatting (long / short / numeric / relative presets, UTC pinning for SSR)
  • useXafRssFeed() — RSS 2.0 XML generation with channel defaults from xAffiliate.brand
  • useXAFStructuredData() — Multi-export JSON-LD composable: useXAFVideoSchema(), useXAFHowToSchema(), useXAFItemListSchema(), useXAFSoftwareApplicationSchema(), useXAFRecipeSchema()

Pages:

  • /affiliate — Public landing page with hero, benefits, commission tiers, and signup form (disable via xAffiliate.pages.landing: false)
  • /affiliate/dashboard — Affiliate dashboard with full metrics and tools; shows a sign-in prompt until useAffiliate() state is populated (disable via xAffiliate.pages.dashboard: false)

Server routes:

  • GET /api/rss — Generic RSS 2.0 feed (empty item list); override with your own server/api/rss.get.ts to feed real content. See BACKEND-REQUIREMENTS.md in the package for the full (minimal) server contract.

App Config Options

The layer exposes two config namespaces — site-wide (xAffiliate covers dashboard + brand + author + legal + tracking) and content (xAffiliateContent covers merchants).

xAffiliate.pages — default-page opt-outs

export default defineAppConfig({
  xAffiliate: {
    pages: {
      landing: true,    // /affiliate — set false to 404 the route
      dashboard: true,  // /affiliate/dashboard — set false to 404 the route
    },
  },
})
export default defineAppConfig({
  xAffiliate: {
    legal: {
      baseUrl: 'https://x.enterprises/legal',
      optIn: {
        health: false,            // → enables <XAFHealthDisclaimer>
        aiContent: false,         // → enables <XAFAIContentDisclosure>
        sponsoredContent: false,  // → enables <XAFSponsoredContentDisclosure>
      },
    },
  },
})

xAffiliate.author — site author identity (E-E-A-T)

export default defineAppConfig({
  xAffiliate: {
    author: {
      name: 'Jane Reviewer',
      role: 'Senior Kitchen Gear Editor',
      bio: '8 years reviewing kitchen equipment for home cooks.',
      image: '/team/jane.jpg',
      credentials: ['CNC-certified reviewer', '8 years testing kitchen gear'],
      social: {
        twitter: 'https://twitter.com/jane',
        linkedin: 'https://linkedin.com/in/jane',
        website: 'https://janereviews.com',
      },
    },
  },
})

xAffiliate.brand — site brand identity

export default defineAppConfig({
  xAffiliate: {
    brand: {
      name: 'BestKitchenGear.com',
      tagline: 'We test so you don\'t have to.',
      logo: 'https://bestkitchengear.com/logo.png',
      url: 'https://bestkitchengear.com',
      ogImage: 'https://bestkitchengear.com/og.png',
      twitter: 'bestkitchengear',
      ogType: 'website',
      locale: 'en_US',
    },
  },
})

xAffiliate.tracking — GTM / GA4 / Clarity

export default defineAppConfig({
  xAffiliate: {
    tracking: {
      gtmId: 'GTM-XXXXXXX',
      ga4Id: 'G-XXXXXXXX',
      clarityId: 'abc123def4',
      autoInject: true,
    },
  },
})

xAffiliateContent — merchant tagging + currency

export default defineAppConfig({
  xAffiliateContent: {
    currency: 'USD',
    locale: 'en-US',
    disclosure: {
      text: 'Affiliate link. We may earn a commission at no cost to you.',
      position: 'above',
    },
    merchants: {
      amazon:  { tagValue: 'yourtag-20' },
      walmart: { tagValue: 'TODO' },
    },
  },
})

Minimal Usage Example

<script setup>
const { affiliate, stats, referralUrl, setAffiliate, setStats } = useAffiliate()

// Your app fetches data and populates state
onMounted(async () => {
  const data = await $fetch('/api/affiliate/me')
  setAffiliate(data.affiliate)
  setStats(data.stats)
})
</script>

<template>
  <XAFDashboard />
</template>

Component Props Reference

XAFBanner

PropTypeDefaultDescription
titlestringrequiredBanner headline text
descriptionstringSubtitle text
ctaLabelstring'Join Now'CTA button label
ctaTostring'/affiliate'CTA link destination
ctaColorstring'white'CTA button color
highlightTextstringHighlight badge text
variant'primary' | 'gradient' | 'dark''gradient'Visual style
showDecorationbooleantrueShow background decoration

XAFSignupForm

PropTypeDefaultDescription
titlestring'Join Our Affiliate Program'Form title
subtitlestring'Earn commissions...'Form subtitle
submitLabelstring'Apply Now'Submit button label
successMessagestring'Application submitted...'Success message after submit
showWebsitebooleantrueShow website URL field
showCompanybooleanfalseShow company name field
showMessagebooleantrueShow promotion strategy textarea

Emits: submit(data: AffiliateFormData)

XAFStatsCards

PropTypeDefaultDescription
statsAffiliateStats | nullrequiredStats data object
currencystring'USD'Currency code for formatting
PropTypeDefaultDescription
affiliateAffiliate | nullrequiredCurrent affiliate data
referralUrlstringrequiredFull referral URL to display and copy

XAFCommissionTiers

PropTypeDefaultDescription
tiersCommissionTier[]requiredArray of commission tier definitions
currentTierIdstring | nullnullID of the affiliate's current tier
nextTierCommissionTier | nullnullNext tier to reach
progressToNextTiernumber0Progress percentage (0–100)

XAFLeaderboard

PropTypeDefaultDescription
entries{ name, referrals, earnings }[]requiredLeaderboard entries
titlestring'Top Affiliates'Section title
periodstring'This Month'Time period badge
currencystring'USD'Currency code

Review-site family props

XAFStarRating

PropTypeDefaultDescription
ratingnumberrequired0 to max. Decimals supported for half-stars. Values outside range are clamped.
maxnumber5Number of stars.
variant'inline' | 'hero''inline'Visual size.
showNumberbooleantrueShow numeric value next to stars.
showScalebooleanfalseShow " / 5" suffix.
color'amber' | 'primary' | 'success' | 'warning''amber'Filled-star color.

Renders with role="img" and a proper aria-label (e.g. "Rated 4.3 out of 5 stars").

XAFBuyButton

The moneymaker — image, price, CTA, disclosure, tagging, and click tracking in one component.

PropTypeDefaultDescription
linkAffiliateLinkFull link object (recommended for MDC).
merchantMerchantId'amazon'Merchant when not passing link.
urlstring'#'Outbound URL when not passing link.
pricenumberPrice for display + currency formatting.
imagestringProduct image URL.
productNamestringAlt text + headline.
labelstringSub-headline.
compactbooleanfalseCompact horizontal layout.
ctaLabelstringfrom merchantOverride the merchant-default CTA label.
color'primary' | 'success' | 'neutral''primary'Button color.
newTabbooleantrueOpen in a new tab.
disabledbooleanfalseRender as a disabled link.
showDisclosurebooleantrueShow the FTC disclosure text.
positionstringPosition label for click tracking (e.g. 'hero', 'sidebar').

Emits: click with { url, merchant, originalUrl }. Pushes affiliate_click to window.dataLayer if GTM / GA4 is loaded (noop otherwise). Renders with rel="sponsored noopener noreferrer" on the anchor for FTC compliance.

Slot-based link when you need full visual control over the CTA.

PropTypeDefaultDescription
merchantMerchantIdrequiredMerchant to tag for.
urlstringrequiredOutbound URL.
tostringRender as <NuxtLink> if internal route.
disabledbooleanfalseRender as a non-interactive span.
newTabbooleantrueOpen in a new tab.

Slot props: { merchant, merchantId, tagged }merchant is the resolved merchant config, tagged is a boolean indicating whether the URL already carries a tag.

Emits: click { url, merchant, originalUrl } and navigate { url }.

XAFProsCons

PropTypeDefaultDescription
prosstring[][]List of pros.
consstring[][]List of cons.
columns1 | 22Number of columns. Auto-collapses to 1 if only one side has content.
prosLabelstring'What we like'Header for the pros section.
consLabelstring"What we don't"Header for the cons section.

Renders an empty-state message when both pros and cons are empty.

XAFDisclosure

FTC disclosure text in 4 visual variants.

PropTypeDefaultDescription
textstringfrom configOverride the disclosure text.
variant'inline' | 'compact' | 'footer' | 'banner''inline'Visual variant.
asstringchosen by variantOverride the HTML tag.
showIconbooleantrue for inline/compactShow the icon.

XAFArticleDisclosure

In-content FTC 16 CFR §255.5 snippet — sits at the top of every review / article page in-flow with the article typography.

PropTypeDefaultDescription
textstringfrom configOverride the disclosure body text.
linkstring'https://x.enterprises/legal/affiliate-disclosure'Override the link URL.
linkLabelstring'Read our full disclosure policy'Override the link label.
publishedAtstring (ISO YYYY-MM-DD)First-published date.
updatedAtstring (ISO YYYY-MM-DD)Last-updated date. Only shown if it differs from publishedAt.
localestring'en-US'Locale for date formatting. Dates are UTC-pinned for SSR stability.

Renders with role="note" and aria-label="Affiliate disclosure".

Composables

useAffiliate()

SSR-safe state management using Nuxt useState. The consuming app calls setters after fetching data from its API.

const {
  config,              // Reactive app config for xAffiliate
  affiliate,           // Affiliate | null
  stats,               // AffiliateStats | null
  referrals,           // Referral[]
  payouts,             // Payout[]
  tiers,               // CommissionTier[]
  isLoading,           // boolean
  error,               // string | null
  isAuthenticated,     // computed — whether affiliate is set
  isActive,            // computed — whether status is 'active'
  referralUrl,         // computed — full referral URL with code
  currentTier,         // computed — current CommissionTier
  nextTier,            // computed — next CommissionTier
  progressToNextTier,  // computed — progress % to next tier
  setAffiliate,
  setStats,
  setReferrals,
  setPayouts,
  setTiers,
  reset,
} = useAffiliate()

useReferralTracking()

Detects referral codes from URL query parameters and persists them in cookies. SSR-safe — cookie operations are guarded by import.meta.server checks.

const {
  referralCode,    // string | null
  referralSource,  // string | null (UTM source)
  detectReferral,  // () => void — detect from URL params or cookie
  clearReferral,   // () => void
  hasReferral,     // () => boolean
  getReferralCode, // () => string | null
} = useReferralTracking()

useAffiliateContent()

Review-site API: merchant config, idempotent link tagging, price formatting, and click tracking.

const {
  config,        // Resolved XAffiliateContentConfig
  getMerchant,   // (id: MerchantId) => XAffiliateContentMerchant
  hasTag,        // (id: MerchantId) => boolean — true if merchant has tagValue set
  taggedUrl,     // (merchant, url) => string — appends tag, idempotent
  taggedLink,    // (link: AffiliateLink) => AffiliateLink
  formatPrice,   // (amount: number) => string — Intl currency
  trackClick,    // (payload) => void — pushes affiliate_click to dataLayer
} = useAffiliateContent()
  • taggedUrl(merchant, url) — appends the configured tag param. Idempotent: re-running on an already-tagged URL returns it unchanged.
  • formatPrice(amount)Intl.NumberFormat with the configured currency / locale.
  • getMerchant(id) / hasTag(id) — display metadata + tag presence checks.
  • trackClick({ url, merchant, position, originalUrl }) — fires affiliate_click to window.dataLayer when GTM is loaded (noop otherwise).

Schema.org JSON-LD

Drive Google star SERPs, FAQ rich results, breadcrumb SERPs, and the Knowledge Panel with one composable per schema type. Each composable injects a <script type="application/ld+json"> block into the page head automatically.

// In a review page's <script setup>:
useProductSchema({
  product: {
    name: 'Wireless Keyboard K1',
    description: 'Compact mechanical keyboard with hot-swappable switches',
    image: 'https://cdn.example.com/k1.jpg',
    brand: 'Logitech',
  },
  ratingValue: 4.6,
  ratingCount: 1234,
  offer: { price: 79.99, priceCurrency: 'USD', availability: 'InStock' },
  datePublished: '2026-01-15',
  reviewBody: 'After 3 months of daily use...',
})

useFAQSchema({
  faqs: [
    { question: 'Is it waterproof?', answer: 'Yes, IPX7 rated.' },
    { question: 'Battery life?', answer: '20 hours with backlight off.' },
  ],
})

useBreadcrumbSchema({
  items: [
    { label: 'Home', href: '/' },
    { label: 'Reviews', href: '/reviews' },
    { label: 'Wireless Keyboards' },
  ],
})

useSiteMeta({
  title: 'Logitech K1 Review: Best Wireless Keyboard of 2026',
  description: 'We tested 12 wireless keyboards. The K1 wins on feel, battery, and price.',
  image: 'https://cdn.example.com/k1-hero.jpg',
  type: 'article',
  publishedTime: '2026-01-15',
  author: 'Jane Reviewer',
})

For site-wide setup (call once in app.vue or a layout):

useOrganizationSchema()
usePersonSchema()           // uses xAffiliate.author
useWebSiteSchema({ searchUrlTemplate: 'https://example.com/search?q={search_term_string}' })

Environment Variables

This layer reads no environment variables directly. All configuration is through app.config.ts.

Layer Architecture

PathPurpose
nuxt.config.tsRegisters @nuxt/ui module and Tailwind CSS
app/app.config.tsAll configurable options under xAffiliate (dashboard + brand + author + legal + tracking) and xAffiliateContent (merchants) namespaces with TypeScript type augmentation
app/app.vueRoot component for the layer
app/composables/useAffiliate, useReferralTracking, useAffiliateContent, useAffiliateImpression, useSchema (multi-export), useXAFConsentTracking, useXafLocale, useXafExperiment, useXAFContentQuery, useXafDateFormat, useXafRssFeed, useXAFStructuredData (multi-export)
app/components/XAF/99 auto-imported components, flat — 10 dashboard-family + 89 review-site-family (FTC-compliant, schema-aware, GTM-tracked), all built on Nuxt UI v4
app/pages//affiliate (landing), /affiliate/dashboard (authenticated) — both opt-out-able via xAffiliate.pages.*
server/api/rss.get.ts — generic RSS 2.0 feed endpoint (empty item list; override in the consumer)
app/types/TypeScript interfaces for Affiliate program, Schema.org shapes, and component prop types

AI Context

package: "@xenterprises/nuxt-x-affiliate"
version: "0.6.0"
use-when: >
  Building a niche affiliate review site on Nuxt 4. v0.6.0 is the
  everything-layer — 99 XAF components + a dozen composable modules
  covering every block on a review page. A consuming site provides
  data; every block is wired.

  Two component families share the XAF prefix and are auto-imported,
  both flat in app/components/XAF/:

  (1) Dashboard family (XAF/*.vue) — 10 components for running your own
      affiliate program (signup forms, referral links, commission tiers,
      stats, authenticated dashboard).

  (2) Review-site family (XAF/*.vue) — 89 components covering:
      - SEO + E-E-A-T: XAFBreadcrumbs, XAFAuthorBox, XAFContributors,
        XAFByline, XAFVerdict, XAFFAQ, XAFLastUpdated, XAFReadingTime,
        XAFPriceVerified, XAFPressLogos, XAFExpertQuote
      - Data: XAFSpecsTable, XAFComparisonTable, XAFScoreBreakdown,
        XAFDecisionMatrix, XAFCalloutBox, XAFQuote, XAFKeyTakeaways,
        XAFTableOfContents, XAFMethodology, XAFSurveyResults,
        XAFCustomerReviews
      - Commerce: XAFHero, XAFProductCard, XAFReviewCard, XAFStickyCTA,
        XAFStarRating, XAFBuyButton, XAFAffiliateLink, XAFProsCons,
        XAFBestFor, XAFDealAlert, XAFWaitlist
      - Legal: XAFDisclosure, XAFArticleDisclosure, XAFAIContentDisclosure,
        XAFSponsoredContentDisclosure, XAFHealthDisclaimer, XAFCookieConsent
      - Social / growth: XAFNewsletter, XAFExitIntent, XAFSocialProof,
        XAFTestimonials, XAFShareReview, XAFPrintButton, XAFReactions,
        XAFSearchBar
      - Engagement / chrome: XAFReadingProgress, XAFBackToTop,
        XAFQuickActions, XAFTagChips
      - Schema-specific: XAFHowTo, XAFRecipe
      - Media: XAFVideoEmbed, XAFGallery, XAFRelatedProducts,
        XAFCompareSlider

  Schema composables (in useSchema) emit JSON-LD for Organization, Person,
  Product + Review + AggregateRating, FAQPage, BreadcrumbList, WebSite
  (with optional SearchAction), Article, HowTo, Recipe, and full meta
  tags (title/description/OG/Twitter/canonical/robots) via useSiteMeta.

  useAffiliateImpression fires affiliate_impression to window.dataLayer
  when a buy button enters the viewport (IntersectionObserver).
  XAFHowTo and XAFRecipe emit their own HowTo/Recipe schema internally.

  Configure site-wide brand + author + legal + tracking under xAffiliate;
  merchant tagging + currency under xAffiliateContent. All 99 components
  are auto-imported — no per-file imports.
Copyright © 2026