JavaScript API
Pixelary tracks page views, forms and clicks on its own. When a conversion happens somewhere only your code knows about, such as a confirmed payment or an accepted booking, send it yourself. One call reaches the browser pixel and the Conversions API, counted once.
Set up
The script defines window.pixelary. Because it loads asynchronously, add the two-line stub before it: calls
made earlier are queued and run in order once Pixelary starts.
<script>
window.pixelary = window.pixelary || function () {
(window.pixelary.q = window.pixelary.q || []).push(arguments);
};
</script>
<script async src="https://cdn.pixelary.app/s/px_7hq2lm4x.js"></script> pixelary(…) never throws. A command with bad arguments is dropped, and the reason is logged in debug mode.
pixelary("track", name, data?, options?) // send an event
pixelary("identify", user) // customer details for the next events
pixelary("consent", values, options?) // the visitor's consent answer
pixelary("config", { auto_events }) // switch automatic events on this page track
pixelary("track", "Purchase",
{
value: 49.9,
currency: "USD",
content_ids: ["sku-1", "sku-2"],
content_type: "product",
content_name: "T-shirt",
num_items: 2,
order_id: "ORD-1001",
coupon: "SPRING", // custom parameter
},
{
event_id: "ORD-1001", // optional; generated when missing
user: { // raw values, this event only
email: "Jane@Example.com",
phone: "+1 555 010 0000",
first_name: "Jane",
last_name: "Doe",
},
}); Event name
These are standard events, matched exactly, case included: PageView, ViewContent,
Search, AddToCart, AddToWishlist, InitiateCheckout,
AddPaymentInfo, Purchase, Lead, CompleteRegistration,
Contact, Schedule, SubmitApplication, StartTrial,
Subscribe. Pixelary sends each platform its own name for them, for example Purchase becomes
CompletePayment on TikTok and order_created on ChatGPT Ads.
Any other name is a custom event: 1 to 50 characters of letters, digits, spaces, _ and -. A name
that breaks the rule is dropped, not renamed. purchase in lower case is a custom event, not a Purchase.
pixelary("track", "Booked call", { value: 0, currency: "EUR" }); Event data
| Field | Type | Rule |
|---|---|---|
| value | number | Finite and 0 or more. A numeric string is accepted. Anything else drops the field. |
| currency | string | ISO 4217, three letters, any case. Required next to value. |
| content_ids | string[] | A single string is taken as a list of one. Empty items are removed. |
| content_type | string | Usually product or product_group. |
| content_name | string | Product or page name. |
| num_items | integer | 0 or more. |
| order_id | string | Your order or transaction ID. |
| any other key | string, number, boolean or a list of them | A custom parameter for platforms that accept them. Up to 25 per event, names up to 50 characters. Objects are dropped. |
A Purchase without value or currency is still sent, with a warning in debug mode.
Options
| Option | Description |
|---|---|
| event_id | Up to 100 characters. The browser and server copies share it on every platform. Without it, Pixelary generates one. A second track with the same ID on the page is ignored. |
| user | Customer details for this event only. Same keys as identify. |
PageView
Pixelary sends page views itself, including route changes in single-page apps. An explicit track("PageView")
for a page that already got its automatic page view is dropped. With auto_events: false, explicit page views
are always sent.
identify
pixelary("identify", {
email: "jane@example.com",
external_id: "u_123",
country: "US",
});
Keys: email, phone, first_name, last_name, external_id,
city, zip, country. Values merge with what the page already knows: a non-empty value
replaces the old one, an empty one is ignored. They are attached to every following event on the page, automatic ones
included. Between pages they are remembered only when the visitor granted both ad_storage and
ad_user_data.
For one event, options.user wins over identify, which wins over what a form provided.
consent
pixelary("consent", { ad_storage: "granted", ad_user_data: "granted" });
pixelary("consent", { ad_personalization: "denied" });
Any of the four Google Consent Mode types, each "granted" or "denied". Types you leave out don’t
change. A type set this way is no longer changed by banners on this page. Events that waited for consent go out once it
is granted. Consent & banners
config
pixelary("config", { auto_events: false });
// …then send page views yourself, for example on every route change:
pixelary("track", "PageView"); auto_events: false stops automatic page views and the form, click and booking triggers from the dashboard on
this page. Your own track calls and dataLayer events keep working. true switches them back on
for what happens next. The setting lasts until the visitor leaves the page.
dataLayer events
On sites with Google Tag Manager but without the Pixelary template, push an event to the dataLayer:
window.dataLayer = window.dataLayer || [];
dataLayer.push({
event: "pixelary",
pixelary_event: "Lead",
pixelary_data: { content_name: "Demo request" },
pixelary_user: { email: "jane@example.com" },
pixelary_event_id: "lead-8421", // optional
}); window.ft from the Framer plugin
Code written for the Framer plugin keeps working. window.ft points to the same API and keeps its three
methods:
window.ft.setConsent(true); // all four consent types
window.ft.meta("Lead", { value: 10, currency: "EUR" }, { email: "jane@example.com" });
window.ft.tiktok("Lead"); ft.meta and ft.tiktok send to one platform only. For new code use pixelary("track", …),
which reaches every connected platform.
TypeScript
declare global {
interface Window {
pixelary: (command: string, ...args: unknown[]) => void;
}
}
export {}; Debug mode
Add ?pixelary_debug=1 to the page address, or run localStorage.pixelary_debug = "1" in the
console. Pixelary then logs every command with the result: sent, waiting for consent, or dropped and why.
Common mistakes
- Hashing customer data yourself. Pass raw values; each platform needs its own normalization.
- A second pixel snippet on the page. A hand-pasted
fbqorttqnext to Pixelary fires events without a shared ID, and they are counted twice. - Purchase without value and currency. The event counts, but value optimization has nothing to work with.
- Calling during server rendering.
window.pixelaryexists only in the browser.
Something here doesn’t match what you see? Write to hello@pixelary.app.