> ## Documentation Index
> Fetch the complete documentation index at: https://docs.affixo.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# v0

> Add Affixo affiliate tracking to a v0 (Next.js) app by pasting one prompt.

v0 builds Next.js App Router apps, so the prompt loads the snippet via
`next/script` in your root layout. Paste it into v0's chat.

<Note>
  Replace `YOUR_PUBLIC_KEY` with your workspace key from **Settings → Tracking**
  (it looks like `pk_live_xxxxxxxx`) before you send the prompt.
</Note>

## The prompt

```text theme={null}
Add Affixo affiliate tracking to my v0 app (Next.js App Router). Three parts — set up all three.

STEP 1 · Tracking script (referral clicks — automatic). In app/layout.tsx, load it on every route:
  import Script from 'next/script'
  <Script async src="https://go.affixo.dev/sa.js?w=YOUR_PUBLIC_KEY" strategy="afterInteractive" />

STEP 2 · Referral event — after a successful signup (in a client component):
  window.Affixo?.track('signup', { email: USER_EMAIL })
  (If signup completes server-side, fire this once on the first authenticated page load instead.)

STEP 3 · Sale event — once on the success page after payment (client component):
  window.Affixo?.track('sale', { email: BUYER_EMAIL, amount: ORDER_TOTAL_MAJOR_UNITS, currency: ORDER_CURRENCY, order_id: ORDER_ID })
  (Tags the buyer for attribution — revenue and commission are confirmed from your connected Stripe.)

STEP 4 · Checkout attribution — REQUIRED however payments are taken. The sale event alone is not enough: the webhook can only credit the referring affiliate if the charge can be tied back to the click — either the checkout carries the Affixo visitor id, or the buyer's email joins them.
Inspect the codebase FIRST and determine how checkout starts, then apply the matching mechanism:
  - Server-created Checkout Session (stripe.checkout.sessions.create):
    - Send the visitor id from the page to your checkout endpoint:
        const vid = window.Affixo?.getVisitorId();
      then set it when creating the session server-side:
        stripe.checkout.sessions.create({ …, metadata: { sa_visitor_id: VISITOR_ID } })
    - One-time checkouts (mode: 'payment') must also set customer_creation: 'always' — Stripe otherwise creates no Customer for a one-off purchase, so the sale records no customer id and repeat purchases by the same buyer can't be tied together. Payment-mode only: do not pass it in subscription mode, which always creates a Customer.
    - For subscriptions, ALSO copy it into subscription_data.metadata, or renewals stop being attributed after the first payment.
  - Payment Link, Buy Button, or Pricing Table (a Stripe-hosted URL or <stripe-*> element):
    - Append the visitor id to the link before redirecting:
        const vid = window.Affixo?.getVisitorId();
        window.location = 'https://buy.stripe.com/XXXX?client_reference_id=' + vid;
    - Do this at click time, not at render time: the id may not exist yet when the page first paints.
      On <stripe-buy-button> / <stripe-pricing-table>, set the client-reference-id attribute instead of a query param.
  - Checkout hosted on ANOTHER platform (a GoHighLevel funnel or order form, Kajabi, ThriveCart, SamCart) that charges the merchant's Stripe account:
    - Write NO Stripe code for this surface. The checkout page isn't ours to amend, so nothing can carry the visitor id into it — attribution reaches the charge by EMAIL instead. The snippet binds the buyer's email as they fill the form, and the charge that lands on the connected Stripe account reconciles to that lead.
    - So the snippet must ALSO load on the page that HOSTS the checkout form, not only on this app. In HighLevel: Sites → Funnels (or Websites) → the funnel → Settings → Head Tracking Code, or the sub-account's account-wide tracking code. On other platforms, their custom-head / tracking-code setting.
    - A form embedded in a CROSS-ORIGIN iframe cannot be read from the page around it. The outer page still records the referral click, but the email capture needs the snippet inside the page serving the form.
    - Tell me if I have not installed the snippet on the checkout platform yet — without it the click is recorded and the sale never joins back to it.
  - If you cannot tell which is in use, ask me which one. All four are supported, so ask in order to pick the right mechanism — never to decide whether Affixo can track the checkout at all.

HOW REVENUE IS CONFIRMED — read this before drawing any conclusion about the checkout:
Affixo confirms money from the merchant's connected Stripe account, and it counts EVERY charge that lands there, whichever platform created it. GoHighLevel order forms, Kajabi, ThriveCart and custom servers all charge that account directly and are handled — it does NOT have to be a Stripe Checkout Session or a Payment Link. Do not tell the merchant their checkout platform can't earn commissions, and do not halt the install over it.
The one hard requirement: the merchant's Stripe account must be connected in Affixo (Settings → Integrations → Stripe), and it must be the SAME Stripe account their checkout charges. Without that connection nothing is confirmed from any checkout at all. Ask me to confirm it is connected before you finish.

First, ask me these and use my answers to place the events correctly:
1. Where do users sign up (which page or component)?
2. What page shows after a successful purchase?
3. Do you charge with Stripe? If yes, how does checkout start — a server-created Checkout Session, a Payment Link / buy button, an embedded form, or a checkout hosted on another platform (GoHighLevel, Kajabi, ThriveCart) that charges your Stripe account? (Determines STEP 4. All of these work — the answer picks the mechanism, not whether tracking is possible.)

Rules: the script must load on every page; use the real signed-in / buyer email (never a placeholder); amount is in MAJOR units — dollars, euros, … ($99.00 = 99.00, NEVER cents: 9900 would register a $9,900 sale) — and currency is the 3-letter code you actually charged (e.g. 'usd', 'eur'); pass a stable order_id on the sale so a refresh or retry never double-counts; don't add any other tracking code. STEP 1 must go in the ROOT layout.
```

## After v0 applies it

Redeploy, then go to **Settings → Tracking** and run the live snippet test
against your deployed URL. A confirmed hit means Step 1 is working. Run the
end-to-end test to confirm the lead and sale events register.

Need the full Next.js snippet reference? See [Integrate Affixo tracking](/integrate).
