{"_id":"@actovision/facebook-conversion-api-nextjs","name":"@actovision/facebook-conversion-api-nextjs","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@actovision/facebook-conversion-api-nextjs","version":"0.1.0","description":"Next.js integration for Meta's Conversions API (CAPI). App Router + Pages Router route handlers, Meta Pixel script loader, browser fbEvent() helper with automatic Pixel + CAPI deduplication, FacebookCapiClient with full parameter coverage (user_data, app_","keywords":["facebook","meta","nextjs","next","conversion","conversions","capi","pixel","app-router","tracking"],"author":{"name":"Actovision"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/actovision/actovision-facebook-conversion-api-nextjs.git"},"type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./server":{"types":"./dist/server/index.d.ts","import":"./dist/server/index.js","require":"./dist/server/index.cjs"},"./client":{"types":"./dist/client/index.d.ts","import":"./dist/client/index.js","require":"./dist/client/index.cjs"},"./components":{"types":"./dist/components/index.d.ts","import":"./dist/components/index.js","require":"./dist/components/index.cjs"}},"sideEffects":false,"scripts":{"build":"tsup","dev":"tsup --watch","test":"vitest run","test:watch":"vitest","typecheck":"tsc --noEmit","clean":"rm -rf dist coverage"},"peerDependencies":{"next":">=16.0.0","react":">=19.0.0","react-dom":">=19.0.0"},"devDependencies":{"@types/node":"^22.9.0","@types/react":"^19.0.0","@types/react-dom":"^19.0.0","next":"^16.2.0","react":"^19.0.0","react-dom":"^19.0.0","tsup":"^8.3.0","typescript":"^5.6.0","vitest":"^2.1.0"},"engines":{"node":">=22.0.0"},"publishConfig":{"access":"public"},"_id":"@actovision/facebook-conversion-api-nextjs@0.1.0","gitHead":"f37a9e561f91e28a0856ac0d1295de1b03938050","bugs":{"url":"https://github.com/actovision/actovision-facebook-conversion-api-nextjs/issues"},"homepage":"https://github.com/actovision/actovision-facebook-conversion-api-nextjs#readme","_nodeVersion":"24.10.0","_npmVersion":"11.6.0","dist":{"integrity":"sha512-VLO4nyZVyI8VHj3n1hb7crZXGQhmSBrFKlTjc1zLUpLOKfCGlC3c9Ua/YY+gy+VdKDvA6UGcGxiBz2UVaCep1Q==","shasum":"d5aec8362ea634b993bdd3f72ab5ea8feb3b1edb","tarball":"https://registry.npmjs.org/@actovision/facebook-conversion-api-nextjs/-/facebook-conversion-api-nextjs-0.1.0.tgz","fileCount":33,"unpackedSize":259929,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCM3W91po08otT3iOr/7ExPbtNdvKhy91z8VxvgvPvhDgIgC6hRN0MUS9ANVmPmlA51BhpYM8NTsaCJAqSt85OXikU="}]},"_npmUser":{"name":"suryak_actovision","email":"surya.k@actovision.in"},"directories":{},"maintainers":[{"name":"suryak_actovision","email":"surya.k@actovision.in"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/facebook-conversion-api-nextjs_0.1.0_1777032293241_0.4439216727893469"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-24T12:04:53.122Z","0.1.0":"2026-04-24T12:04:53.397Z","modified":"2026-04-24T12:04:53.647Z"},"maintainers":[{"name":"suryak_actovision","email":"surya.k@actovision.in"}],"description":"Next.js integration for Meta's Conversions API (CAPI). App Router + Pages Router route handlers, Meta Pixel script loader, browser fbEvent() helper with automatic Pixel + CAPI deduplication, FacebookCapiClient with full parameter coverage (user_data, app_","homepage":"https://github.com/actovision/actovision-facebook-conversion-api-nextjs#readme","keywords":["facebook","meta","nextjs","next","conversion","conversions","capi","pixel","app-router","tracking"],"repository":{"type":"git","url":"git+https://github.com/actovision/actovision-facebook-conversion-api-nextjs.git"},"author":{"name":"Actovision"},"bugs":{"url":"https://github.com/actovision/actovision-facebook-conversion-api-nextjs/issues"},"license":"MIT","readme":"# @actovision/facebook-conversion-api-nextjs\n\nNext.js integration for [Meta's Conversions API](https://developers.facebook.com/docs/marketing-api/conversions-api/). Supports **App Router** and **Pages Router**. Fully self-contained — talks to the Meta Graph API directly, no companion package required.\n\n- Server-side CAPI handler (App Router **and** Pages Router)\n- Browser helper `fbEvent()` that fires the pixel + the server event with matching `eventId` for automatic deduplication\n- Meta Pixel `<Script>` loader and a pageview provider for each router\n- Full parameter coverage: every standard event, every `user_data` field (including `madid`, `anon_id`, `ctwa_clid`, `ig_account_id`, `ig_sid`, `page_id`, `page_scoped_user_id`), `app_data` for app-source events, `referrer_url`, LDU/CCPA, test events, deduplication\n- Auto-detects `cf-connecting-ip` / `x-real-ip` / `x-forwarded-for`, `Referer`, and reconstructs `fbc` from `fbclid` when the `_fbc` cookie is absent\n- Defaults to Graph API **v22.0** — configurable via `apiVersion`\n- Zero runtime dependencies — only `next` + `react` peers\n\n## Install\n\n```bash\npnpm add @actovision/facebook-conversion-api-nextjs\n# peers: next >= 16, react >= 19 — node >= 22\n```\n\n## Environment\n\n```\nFB_ACCESS_TOKEN=<your server-only CAPI token>\nNEXT_PUBLIC_FB_PIXEL_ID=<your pixel id>\n```\n\n## App Router setup\n\n**1. Mount the pixel script + provider in your root layout**\n\n```tsx\n// app/layout.tsx\nimport { FBPixelScript, FBPixelProvider } from '@actovision/facebook-conversion-api-nextjs/components'\n\nexport default function RootLayout({ children }: { children: React.ReactNode }) {\n  return (\n    <html>\n      <body>\n        <FBPixelScript pixelId={process.env.NEXT_PUBLIC_FB_PIXEL_ID!} />\n        <FBPixelProvider>{children}</FBPixelProvider>\n      </body>\n    </html>\n  )\n}\n```\n\n**2. Add the server route**\n\n```ts\n// app/api/fb-events/route.ts\nimport { createFbEventsRouteHandler } from '@actovision/facebook-conversion-api-nextjs/server'\n\nexport const { POST } = createFbEventsRouteHandler({\n  accessToken: process.env.FB_ACCESS_TOKEN!,\n  pixelId: process.env.NEXT_PUBLIC_FB_PIXEL_ID!,\n})\n```\n\n**3. Fire events from client components**\n\n```tsx\n'use client'\nimport { fbEvent } from '@actovision/facebook-conversion-api-nextjs/client'\n\nexport function BuyButton() {\n  return (\n    <button\n      onClick={() =>\n        fbEvent({\n          eventName: 'Purchase',\n          emails: ['customer@example.com'],\n          value: 99.99,\n          currency: 'USD',\n        })\n      }\n    >\n      Buy\n    </button>\n  )\n}\n```\n\n## Pages Router setup\n\n```tsx\n// pages/_app.tsx\nimport {\n  FBPixelScript,\n  FBPixelProviderPages,\n} from '@actovision/facebook-conversion-api-nextjs/components'\n\nexport default function App({ Component, pageProps }) {\n  return (\n    <>\n      <FBPixelScript pixelId={process.env.NEXT_PUBLIC_FB_PIXEL_ID!} />\n      <FBPixelProviderPages>\n        <Component {...pageProps} />\n      </FBPixelProviderPages>\n    </>\n  )\n}\n```\n\n```ts\n// pages/api/fb-events.ts\nimport { createFbEventsApiHandler } from '@actovision/facebook-conversion-api-nextjs/server'\n\nexport default createFbEventsApiHandler({\n  accessToken: process.env.FB_ACCESS_TOKEN!,\n  pixelId: process.env.NEXT_PUBLIC_FB_PIXEL_ID!,\n})\n```\n\nClient-side `fbEvent()` works identically.\n\n## Standard events\n\nEvery Meta standard event is supported. `fbEvent()` fires both the browser pixel and the server event with the same `eventId` for automatic deduplication. Event names are case-sensitive — use the names exactly as shown.\n\n```ts\n'use client'\nimport { fbEvent } from '@actovision/facebook-conversion-api-nextjs/client'\n\n// Purchase — completed transaction\nfbEvent({\n  eventName: 'Purchase',\n  emails: ['customer@example.com'],\n  phones: ['+1 555 123 4567'],\n  value: 99.99,\n  currency: 'USD',\n  order_id: 'ORDER-12345',\n  contents: [{ id: 'sku-1', quantity: 1, item_price: 99.99 }],\n  content_ids: ['sku-1'],\n  content_type: 'product',\n})\n\n// AddToCart — user added an item to cart\nfbEvent({\n  eventName: 'AddToCart',\n  content_ids: ['sku-1'],\n  contents: [{ id: 'sku-1', quantity: 1, item_price: 49.99 }],\n  content_type: 'product',\n  value: 49.99,\n  currency: 'USD',\n})\n\n// InitiateCheckout — user started checkout\nfbEvent({\n  eventName: 'InitiateCheckout',\n  content_ids: ['sku-1', 'sku-2'],\n  num_items: 2,\n  value: 79.98,\n  currency: 'USD',\n})\n\n// AddPaymentInfo — user entered payment info\nfbEvent({\n  eventName: 'AddPaymentInfo',\n  value: 79.98,\n  currency: 'USD',\n})\n\n// ViewContent — user viewed a product / content page\nfbEvent({\n  eventName: 'ViewContent',\n  content_ids: ['sku-1'],\n  content_name: 'Running Shoes',\n  content_category: 'Footwear',\n  content_type: 'product',\n  value: 49.99,\n  currency: 'USD',\n})\n\n// Search — user performed a search\nfbEvent({\n  eventName: 'Search',\n  search_string: 'running shoes',\n  content_ids: ['sku-1', 'sku-2'],\n  content_category: 'Footwear',\n})\n\n// Lead — form / quote submission\nfbEvent({\n  eventName: 'Lead',\n  emails: ['lead@example.com'],\n  phones: ['+1 555 000 1111'],\n  content_name: 'Newsletter Signup',\n  value: 0,\n  currency: 'USD',\n})\n\n// CompleteRegistration — account created\nfbEvent({\n  eventName: 'CompleteRegistration',\n  emails: ['new@example.com'],\n  content_name: 'Free Plan',\n  status: 'completed',\n  value: 0,\n  currency: 'USD',\n})\n\n// Subscribe — paid subscription started\nfbEvent({\n  eventName: 'Subscribe',\n  emails: ['user@example.com'],\n  value: 9.99,\n  currency: 'USD',\n  predicted_ltv: 120,\n})\n\n// StartTrial — free trial activated\nfbEvent({\n  eventName: 'StartTrial',\n  emails: ['trial@example.com'],\n  value: 0,\n  currency: 'USD',\n  predicted_ltv: 120,\n})\n\n// AddToWishlist — user saved item to wishlist\nfbEvent({\n  eventName: 'AddToWishlist',\n  content_ids: ['sku-1'],\n  value: 49.99,\n  currency: 'USD',\n})\n\n// FindLocation — looked up a physical business location\nfbEvent({ eventName: 'FindLocation', content_name: 'Downtown Store' })\n\n// Schedule — booked an appointment\nfbEvent({\n  eventName: 'Schedule',\n  emails: ['appt@example.com'],\n  content_name: 'Consultation',\n})\n\n// SubmitApplication — applied for product/service\nfbEvent({\n  eventName: 'SubmitApplication',\n  emails: ['applicant@example.com'],\n  value: 0,\n  currency: 'USD',\n})\n\n// Donate — donation completed\nfbEvent({\n  eventName: 'Donate',\n  emails: ['donor@example.com'],\n  value: 25,\n  currency: 'USD',\n})\n\n// Contact — initiated contact (support, sales, etc.)\nfbEvent({ eventName: 'Contact', emails: ['contact@example.com'] })\n\n// PageView — usually auto-fired by FBPixelProvider. Call manually only for\n// virtual page transitions your provider can't detect:\nfbEvent({ eventName: 'PageView' })\n```\n\nNeed a custom event? Pass any string for `eventName` — typed as `EventName = StandardEventName | (string & {})`.\n\n## How deduplication works\n\n`fbEvent()` generates a single `eventId`, fires `fbq('track', name, payload, { eventID })` on the client, waits a short moment (default 250 ms), then POSTs the same `eventId` to `/api/fb-events`. Meta collapses the two deliveries into one attributed event.\n\n## API reference\n\n### Client\n\n| Symbol | Description |\n| --- | --- |\n| `fbEvent(options)` | Fire pixel + server event. Returns `{ eventId, serverResponse }`. |\n| `fbPageView()` | Standard pixel PageView (client-only). |\n\n### Server\n\n| Symbol | Description |\n| --- | --- |\n| `createFbEventsRouteHandler(opts)` | App Router. Returns `{ POST }` for `app/api/fb-events/route.ts`. |\n| `createFbEventsApiHandler(opts)` | Pages Router. Default export for `pages/api/fb-events.ts`. |\n| `signalsFromRequest`, `signalsFromNodeRequest` | Pull IP, UA, `_fbp`, `_fbc` from a request. |\n| `buildServerEvent` | Build a `ServerEvent` from a flat payload — useful if you write your own handler. |\n\nBoth factory handlers accept every `FacebookCapiClientOptions` plus:\n- `actionSource` — default for `action_source` (default `'website'`)\n- `apiVersion` — Graph API version (default `'v22.0'`)\n- `testEventCode` — Meta Test Events tab code; removed in production\n- `timeoutMs` / `retries` — network tuning (defaults 10 s / 2 retries on 5xx)\n- `transformEvent` — last-chance mutator before sending\n- `debug` — echo the payload + Meta response in the HTTP response body\n\n### App events (`action_source: 'app'`)\n\nPass `appData` on either the client `fbEvent()` call or the server `ServerEvent`:\n\n```ts\nfbEvent({\n  eventName: 'Purchase',\n  value: 9.99,\n  currency: 'USD',\n  appData: {\n    advertiserTrackingEnabled: 1,           // iOS ATT consent\n    applicationTrackingEnabled: 1,\n    extinfo: ['i2', 'com.example.app', '1.0', '1', '17.0', 'iPhone15,2', 'en_US', 'PST', 'Verizon', 390, 844, 3, 6, 8, 128],\n    vendorId: 'vid-...',\n  },\n})\n```\n\n### Landing-page `fbclid` capture\n\nWhen a user arrives from an ad without the `_fbc` cookie yet being set (e.g. no Pixel on the landing page), the server handler reconstructs `fbc` as `fb.1.{nowMs}.{fbclid}` from the request URL. No action required.\n\n### Components\n\n| Symbol | Description |\n| --- | --- |\n| `<FBPixelScript pixelId nonce? strategy? />` | Inline Meta Pixel init via `next/script`. |\n| `<FBPixelProvider>` | **App Router** — fires PageView on pathname/searchParams change. |\n| `<FBPixelProviderPages>` | **Pages Router** — fires PageView on `routeChangeComplete`. |\n\n## License\n\n[MIT](./LICENSE) © 2026 [Actovision](https://github.com/actovision).\n\nFree to use in commercial and open-source projects. The license text must be included in copies or substantial portions of the software.\n","readmeFilename":"README.md","_rev":"1-73f63650d3f746d04cf095b15f170a73"}