Skip to content
adscapi

Next.js

Call conversions.track() from an App Router route handler or server action. Keep platform tokens on the server — never import adscapi into a Client Component.

Install

shell
npm install adscapi

Environment

Put platform secrets in .env.local (or your host’s env UI). createAdscapi() reads process.env.

env
# .env.local (never commit real tokens)
META_CAPI_TOKEN=…
META_PIXEL_ID=…
GA4_MEASUREMENT_ID=…
GA4_API_SECRET=…

Route handler

ts
// app/api/track/route.ts
import { createAdscapi } from 'adscapi';
import { NextResponse } from 'next/server';

// Module-scope client — reuses across warm invocations.
const ads = createAdscapi();

export async function POST(request: Request) {
  const body = await request.json();

  const results = await ads.conversions.track({
    name: body.name ?? 'purchase',
    value: body.value,
    currency: body.currency ?? 'USD',
    transactionId: body.orderId,
    user: {
      email: body.email,
      phone: body.phone,
      ip: request.headers.get('x-forwarded-for') ?? undefined,
      userAgent: request.headers.get('user-agent') ?? undefined,
      fbc: body.fbc,
      fbp: body.fbp,
    },
    clickIds: {
      gclid: body.gclid,
      fbclid: body.fbclid,
    },
    consent: {
      adUserData: Boolean(body.consent?.adUserData),
      adPersonalization: Boolean(body.consent?.adPersonalization),
    },
  });

  return NextResponse.json({ results });
}

Fire this from your checkout success path (server-side) after the order is confirmed. Pass raw email/phone plus any click IDs and browser cookies you captured on the client.

Server Action (optional)

ts
// app/checkout/actions.ts
'use server';

import { createAdscapi } from 'adscapi';

const ads = createAdscapi();

export async function trackPurchase(input: {
  email: string;
  amount: number;
  orderId: string;
  consent: { adUserData: boolean; adPersonalization: boolean };
}) {
  return ads.conversions.track({
    name: 'purchase',
    value: input.amount,
    currency: 'USD',
    transactionId: input.orderId,
    user: { email: input.email },
    consent: input.consent,
  });
}

Staging & test events

ts
// Dry-run in preview / staging
await ads.conversions.track(event, { dryRun: process.env.VERCEL_ENV !== 'production' });

// Meta Test Events during QA
await ads.conversions.track(event, {
  testEventCodes: { meta: process.env.META_TEST_EVENT_CODE! },
});

Edge runtime

The dispatch path uses only fetch and WebCrypto, so it runs under export const runtime = 'edge' and on Cloudflare Workers. See the Workers guide if you deploy Next via OpenNext.

Next