Skip to main content
Meta Ads support is completely optional. If you don’t run Meta Ads, you can skip this entirely.

What This Does

This feature tracks the two Meta events most people care about for paid traffic:
  • InitiateCheckout — when someone clicks a checkout button
  • Purchase — when the payment webhook succeeds and the purchase is stored
That gives you clean ad performance measurement without forcing Meta code into the generic analytics layer.

Why It’s Separate From Analytics

In this repo:
  • Product analytics live under lib/analytics/*
  • Meta checkout attribution lives under lib/attribution/meta/*
That split is intentional. PostHog, Plausible, and DataFast are general analytics tools. Meta Ads is a paid acquisition channel with its own tracking requirements. Keeping them separate means you’re never forced to enable Meta just because the feature exists.

Setup

1

Get your Meta credentials

You’ll need your Meta Pixel ID and a Conversions API access token from Meta Events Manager.
2

Add env vars

NEXT_PUBLIC_ENABLE_META_ATTRIBUTION=true
NEXT_PUBLIC_META_PIXEL_ID=your-pixel-id
META_ACCESS_TOKEN=your-access-token
Optional for testing:
NEXT_PUBLIC_META_TEST_EVENT_CODE=your-test-code
3

Restart the app

The Meta Pixel only loads when NEXT_PUBLIC_ENABLE_META_ATTRIBUTION=true and the required values are present.
4

Test with a checkout flow

Click a checkout button and complete a purchase. Check Meta Events Manager to confirm both events fire.

How the Flow Works

  1. A user clicks a checkout CTA rendered through CheckoutLink
  2. The repo sends Meta InitiateCheckout in the browser
  3. The payment provider completes checkout
  4. Your webhook is verified by the shared payment route
  5. The purchase is stored by the shared payment processor
  6. The repo sends Meta Purchase through Conversions API
Only checkout buttons that go through the shared checkout abstraction get the Meta browser event automatically. Use components/(ui-components)/payments/checkout-link.tsx for your CTAs. Hardcoded raw checkout URLs in random UI files will not trigger Meta events.

What Meta Receives

The implementation sends:
  • Product/content identifiers from the shared checkout catalog
  • Value and currency
  • Hashed user identity data when available
  • A stable event ID for purchase deduplication
The purchase event is emitted after the purchase row is inserted — the safest place to do it.

Key Files

  • lib/attribution/meta/provider.tsx — Meta provider component
  • lib/attribution/meta/browser.ts — browser-side pixel events
  • lib/attribution/meta/conversions-api.ts — server-side Conversions API
  • components/(ui-components)/payments/checkout-link.tsx — checkout CTA component
  • lib/payments/processor.ts — where purchase events fire

Verify It Works

Your Meta Ads setup is working if:
  • The Meta Pixel loads only when enabled
  • Clicking a checkout CTA triggers InitiateCheckout
  • A successful purchase webhook triggers Purchase
  • Events appear in Meta Events Manager
For testing, set NEXT_PUBLIC_META_TEST_EVENT_CODE and confirm test events appear under that code in Events Manager.
Make sure your checkout buttons use the CheckoutLink component, not hardcoded URLs.
Check that META_ACCESS_TOKEN is set. The Purchase event goes through the server-side Conversions API, which needs the token.
Double-check your Pixel ID. Also verify that checkout URLs are present in your env — the Meta feature won’t fire events if there’s nothing to check out.

Payments

See how hosted checkout links and payment webhooks work in the repo.

Analytics

Read about the separate product analytics layer for PostHog, Plausible, and DataFast.