Skip to main content
Meta Ads support in this repo is optional. If you do not run Meta Ads, you do not need to enable any of this.

What This Feature Does

This repo can help you track the two Meta events most people care about for paid traffic:
  • InitiateCheckout when someone clicks a hosted checkout CTA
  • Purchase when the payment webhook succeeds and the purchase is stored
That gives you a clean way to measure ad performance without forcing Meta code into the generic analytics layer.

Why Meta Ads Is 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 it separate means template users are not forced to enable Meta just because the feature exists.

Required Env Vars

Enable Meta attribution only when you actually want it:
NEXT_PUBLIC_ENABLE_META_ATTRIBUTION=true
NEXT_PUBLIC_META_PIXEL_ID=...
META_ACCESS_TOKEN=...
Optional:
NEXT_PUBLIC_META_TEST_EVENT_CODE=...
# META_GRAPH_API_VERSION=v22.0
If NEXT_PUBLIC_ENABLE_META_ATTRIBUTION is false or the required Meta values are missing, the feature stays off.

How The Repo Is Wired

The main files are:
  • lib/attribution/meta/provider.tsx
  • lib/attribution/meta/browser.ts
  • lib/attribution/meta/conversions-api.ts
  • components/(ui-components)/payments/checkout-link.tsx
  • lib/payments/processor.ts
The flow works like this:
  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

Important Constraint

Only checkout buttons that go through the shared checkout abstraction get the Meta browser event automatically. That means you should use:
  • components/(ui-components)/payments/checkout-link.tsx
and avoid:
  • hardcoded raw checkout URLs directly inside random UI files

What Meta Receives

The current 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 from the canonical payment flow after the purchase row is inserted, which is the safest place to do it.

Verification Checklist

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
  • the events appear in Meta Events Manager
If you are testing, set NEXT_PUBLIC_META_TEST_EVENT_CODE and confirm the test events appear under that code.

Common Mistakes

  • setting NEXT_PUBLIC_META_PIXEL_ID but forgetting META_ACCESS_TOKEN
  • expecting Meta events from a CTA that does not use CheckoutLink
  • enabling Meta while checkout URLs are still missing from env
  • mixing generic analytics expectations with Meta attribution expectations
  • changing env vars without restarting the app