Pixel helpers
Client-side click-id capture → first-party cookie → server-side parseClickIds() → conversions.track({ clickIds }). No third-party pixels required.
pixelSnippet(opts?)
ts
import { pixelSnippet, parseClickIds, CLICK_ID_PARAMS } from 'adscapi';
// Returns a minimal JS string to embed in a <script> tag
const js: string = pixelSnippet({
endpoint?: string, // optional POST target for { clickIds, url }
cookie?: string, // first-party cookie name (default: '_adscapi')
});On load the snippet:
- Reads
CLICK_ID_PARAMSfromlocation.search - Reads Meta’s
_fbc/_fbpcookies - Merges with the existing first-party cookie (default name
_adscapi, ~90 days,SameSite=Lax) - Writes the cookie back
- If
endpointis set,POSTs{ clickIds, url }as JSON withkeepalive
Inputs are JSON-escaped. No external calls beyond the optional endpoint POST. Dependency-free — safe to drop into any page.
parseClickIds(input)
ts
// Server-side: normalize a captured bag into ConversionClickIds const clickIds = parseClickIds( input: Record<string, string | undefined> | string | null | undefined, ): ConversionClickIds; // Accepts a parsed object OR a JSON string (e.g. cookie value). Never throws.
Keeps known keys + any key matching /clid$|_click|callback|braid/i. Drops empty values. Never throws — bad JSON becomes {}.
CLICK_ID_PARAMS
ts
const CLICK_ID_PARAMS: Record<string, string> = {
gclid: 'gclid',
fbclid: 'fbclid',
msclkid: 'msclkid',
ttclid: 'ttclid',
twclid: 'twclid',
ob_click_id: 'ob_click_id',
li_fat_id: 'li_fat_id',
gbraid: 'gbraid',
wbraid: 'wbraid',
epik: 'epik', // Pinterest
sccid: 'sccid', // Snapchat
};Example
ts
// --- client: app/layout.tsx (or any page <head>) ---
import { pixelSnippet } from 'adscapi';
export default function RootLayout({ children }) {
const snippet = pixelSnippet({
endpoint: '/api/click-ids', // optional beacon
cookie: '_adscapi',
});
return (
<html>
<head>
<script dangerouslySetInnerHTML={{ __html: snippet }} />
</head>
<body>{children}</body>
</html>
);
}
// --- server: read the cookie and track ---
import { createAdscapi, parseClickIds } from 'adscapi';
import { cookies } from 'next/headers';
const ads = createAdscapi();
export async function POST(req: Request) {
const body = await req.json();
const jar = await cookies();
const clickIds = parseClickIds(jar.get('_adscapi')?.value);
// or merge with anything the client POSTed:
// const clickIds = parseClickIds({ ...JSON.parse(jar.get('_adscapi')?.value ?? '{}'), ...body.clickIds });
await ads.conversions.track({
name: 'purchase',
value: body.amount,
currency: 'USD',
user: { email: body.email },
clickIds,
consent: { adUserData: true, adPersonalization: true },
});
return Response.json({ ok: true });
}Related
- conversions.track() — pass the parsed bag as
clickIds - Next.js guide