next-meta-pixel
v0.1.0
Published
Facebook Pixel + Conversions API for Next.js App Router. Dual client/server tracking with automatic deduplication.
Maintainers
Readme
next-meta-pixel
Facebook Pixel + Conversions API (CAPI) for Next.js App Router.
Dual client/server event tracking with automatic deduplication, PII hashing, and TypeScript support.
Features
- Pixel + CAPI — Send events to both browser and server for maximum attribution
- Auto-deduplication — Shared event IDs prevent double-counting
- PII hashing — SHA256 hashing of emails, phones, names before sending to Meta
- App Router — Built for Next.js 13+ App Router with
"use client"components - TypeScript — Full type safety with exported interfaces
- Dev mode — Mock responses and fallback cookies in development
- Zero dependencies — Only
nextandreactas peer deps
Quick Start
1. Install
npm install next-meta-pixel2. Add environment variables
# .env.local
NEXT_PUBLIC_FB_PIXEL_ID=123456789 # Your Pixel ID
FB_PIXEL_ACCESS_TOKEN=EAAx... # Access token (for CAPI, server-side only)3. Add to your layout
// app/layout.tsx
import { FacebookPixel, PixelPageView } from "next-meta-pixel";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
{children}
<FacebookPixel />
<PixelPageView />
</body>
</html>
);
}4. Create the API route (for CAPI)
// app/api/fb-events/route.ts
import { fbEventsHandler } from "next-meta-pixel/handlers";
export const POST = fbEventsHandler;5. Track events
import { fbEvent } from "next-meta-pixel";
// Track a lead
fbEvent({ eventName: "Lead" });
// Track with data + PII for better CAPI matching
fbEvent({
eventName: "Lead",
data: { content_name: "signup-form" },
emails: ["[email protected]"],
phones: ["+972501234567"],
});API Reference
Components
<FacebookPixel />
Loads the Facebook Pixel script. Add once in your root layout.
<PixelPageView />
Tracks PageView on every route change. Add alongside <FacebookPixel />.
Client Functions
fbEvent(options)
Track an event on both Pixel (client) and CAPI (server).
fbEvent({
eventName: "Purchase", // Required — standard or custom event name
data: { // Optional — event parameters
value: 29.99,
currency: "USD",
},
emails: ["[email protected]"], // Optional — hashed and sent via CAPI
phones: ["+1234567890"], // Optional — hashed and sent via CAPI
firstName: "John", // Optional
lastName: "Doe", // Optional
apiRoute: "/api/fb-events", // Optional — default: "/api/fb-events"
});Facebook standard events: Lead, Purchase, AddToCart, InitiateCheckout, ViewContent, CompleteRegistration, Subscribe, Search, etc.
usePixel()
React hook wrapper for fbEvent.
const { track } = usePixel();
track({ eventName: "AddToCart", data: { value: 19.99 } });trackStandardEvent(name, options?, eventID?)
Low-level: fires fbq('track', ...) only (no CAPI).
trackCustomEvent(name, options, eventID)
Low-level: fires fbq('trackCustom', ...) only (no CAPI).
Server Functions
sendServerEvent(eventData)
Send an event directly to Facebook's Conversions API. Use this for server-side events (e.g., in API routes or Server Actions).
import { sendServerEvent } from "next-meta-pixel/server";
await sendServerEvent({
eventName: "Lead",
eventId: "unique-uuid",
emails: ["[email protected]"],
phones: ["+972501234567"],
sourceUrl: "https://example.com/form",
});Handler
fbEventsHandler
Pre-built Next.js POST handler for the CAPI API route.
// app/api/fb-events/route.ts
import { fbEventsHandler } from "next-meta-pixel/handlers";
export const POST = fbEventsHandler;Environment Variables
| Variable | Required | Side | Description |
|---|---|---|---|
| NEXT_PUBLIC_FB_PIXEL_ID | Yes | Client + Server | Your Facebook Pixel ID |
| FB_PIXEL_ACCESS_TOKEN | For CAPI | Server only | System User access token |
| FB_TEST_EVENT_CODE | No | Server only | Test event code for development |
How Deduplication Works
When you call fbEvent():
- A unique
eventId(UUID v4) is generated - The same
eventIdis sent to both:- Client:
fbq('track', 'Lead', { eventID: '...' }) - Server: POST
/api/fb-events→ Facebook CAPI withevent_id: '...'
- Client:
- Facebook matches the two events by
event_idand counts them once
This ensures you get the best of both worlds — immediate client-side tracking plus reliable server-side attribution.
Cookie Consent
This package does not enforce cookie consent. If you need consent gating, conditionally render the components:
function Layout({ children }) {
const hasConsent = useCookieConsent(); // your consent hook
return (
<>
{children}
{hasConsent && <FacebookPixel />}
{hasConsent && <PixelPageView />}
</>
);
}The fbEvent() function will silently no-op if the pixel script hasn't been loaded.
CSP (Content Security Policy)
If you use CSP headers, add these domains:
script-src: https://connect.facebook.net
connect-src: https://connect.facebook.net https://www.facebook.com
img-src: https://www.facebook.comDevelopment Mode
In development (NODE_ENV=development):
- The API route handler returns mock responses (no real Facebook API calls)
- Missing
_fbp/_fbccookies are replaced with realistic fallbacks - All events are logged to the console with
[next-meta-pixel]prefix - Set
FB_TEST_EVENT_CODEto test with Facebook's Test Events tool
License
MIT
