Next.js
Load the script once in the root layout with next/script. Pixelary follows client-side navigation, so every route change is a page view.
1 App Router
Add both scripts to the root layout. The first one queues calls made before Pixelary has loaded.
// app/layout.tsx
import Script from "next/script";
const PIXELARY = "https://cdn.pixelary.app/s/px_7hq2lm4x.js";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
{children}
<Script id="pixelary-queue" strategy="afterInteractive">
{`window.pixelary = window.pixelary || function () {
(window.pixelary.q = window.pixelary.q || []).push(arguments);
};`}
</Script>
<Script src={PIXELARY} strategy="afterInteractive" />
</body>
</html>
);
} 2 Pages Router
With the Pages Router, load both scripts in _app.tsx:
// pages/_app.tsx
import type { AppProps } from "next/app";
import Script from "next/script";
export default function App({ Component, pageProps }: AppProps) {
return (
<>
<Component {...pageProps} />
<Script id="pixelary-queue" strategy="afterInteractive">
{`window.pixelary = window.pixelary || function () {
(window.pixelary.q = window.pixelary.q || []).push(arguments);
};`}
</Script>
<Script src="https://cdn.pixelary.app/s/px_7hq2lm4x.js" strategy="afterInteractive" />
</>
);
} 3 Send conversions
Call window.pixelary from client components when something worth reporting happens. Pass your own order ID
as event_id if your backend sends the same purchase to the platforms: the platform then counts it once.
"use client";
export function CheckoutButton({ order }: { order: Order }) {
async function pay() {
const paid = await checkout(order);
window.pixelary("track", "Purchase",
{ value: paid.total, currency: paid.currency, order_id: paid.id },
{ event_id: paid.id, user: { email: paid.email } });
}
return <button onClick={pay}>Pay</button>;
} Declare the global once for TypeScript:
// pixelary.d.ts
declare global {
interface Window {
pixelary: (command: string, ...args: unknown[]) => void;
}
}
export {}; Content Security Policy
If you set a CSP in next.config.js or middleware, allow https://cdn.pixelary.app in
script-src and https://api.pixelary.app in connect-src, plus the pixels you use.
The full list is in the HTML snippet guide.
Consent banner
Pixelary sends nothing a visitor has declined. In the EEA, the UK and Switzerland it waits for the visitor’s yes before any pixel loads or any event leaves the page.
Pixelary reads these on its own, with no extra setup:
- Google Consent Mode v2
- IAB TCF 2.2
- Global Privacy Control
- Cookiebot
- OneTrust
- CookieYes
- Usercentrics
- Complianz
- iubenda
- Termly
- Osano
- CookieFirst
- Didomi (via TCF)
- Framer cookie banner
Another banner can pass its answer with one line of code. Consent & banners
Something here doesn’t match what you see? Write to hello@pixelary.app.