SDK API
The window.pixelfox surface, init options and what the tag stores.
The PixelFox tag exposes a global window.pixelfox object once loaded. Every method is
safe to call before the tag has finished booting: calls made too early are dropped,
never thrown.
Methods
Tracking
| Method | Signature | Notes |
|---|---|---|
init | init(options?) | Called automatically on load unless data-no-init="true". Idempotent - the second call is a no-op |
track | track(event, properties?) | Queue an event (batched; flushed every 10 s, at 20 events, and on page hide). Also fires the matching browser pixel and feeds surveys and promos |
trackFromTarget | trackFromTarget(event, target, properties?) | Like track, but honors data-pixelfox-no-capture on the target's ancestors |
setSuperProperties | setSuperProperties(props) | Merge properties attached to every future event |
flush | flush() | Force-send the current batch |
Identity
| Method | Signature | Notes |
|---|---|---|
identify | identify(distinctId, properties?) | Switch to a known-user id and send $identify. Include email/phone in properties to power identity stitching |
alias | alias(newId) | Record an alias then switch the distinct id |
group | group(type, key, properties?) | Send $groupidentify |
reset | reset() | Clear identity + super properties and mint a fresh anonymous id (use on logout). The device id is kept |
getDistinctId | getDistinctId(): string | The current visitor id |
Consent and opt-out
| Method | Signature | Notes |
|---|---|---|
optOut / optIn | optOut() / optIn() | Persistently disable/enable all tracking for this browser. optOut also removes the device id |
hasOptedOut | hasOptedOut(): boolean | True when opted out or the browser sends Do-Not-Track |
updateConsent | updateConsent("granted" | "denied" | partialState) | Google Consent Mode v2 update from your banner. A partial state is any of ad_storage, ad_user_data, ad_personalization, analytics_storage, each "granted" or "denied". See Consent Mode |
Surveys and promos
These control the dashboard-authored surveys and promos. They are no-ops until the engage bundle has loaded, which happens only when the site has something active.
| Method | Signature | Notes |
|---|---|---|
showSurvey | showSurvey(key): boolean | Show a survey by key, bypassing its trigger. Returns false if it is not active |
dismissSurvey | dismissSurvey() | Close the open survey |
showPromo | showPromo(key): boolean | Show a promo by key, bypassing its frequency cap |
dismissPromo | dismissPromo() | Close the open promo |
onSurveys | onSurveys(cb): unsubscribe | Called with the active surveys once they are loaded (immediately if they already are). Returns a function that removes the listener |
pixelfox.updateConsent({ ad_storage: "denied", analytics_storage: "granted" });
const stop = pixelfox.onSurveys((surveys) => {
if (surveys.some((s) => s.key === "post-purchase")) pixelfox.showSurvey("post-purchase");
});Init options
pixelfox.init({
apiKey: "pfx_live_…", // required (or data-pixelfox-key)
host: "https://api.pixelfox.app", // ingest API base URL (or data-pixelfox-host)
autocapture: true, // clicks/submits/pageviews/forms (default true)
inventory: true, // element auto-discovery (default true)
remoteEvents: true, // dashboard-defined definitions (default true)
vendorTags: true, // Clarity/Meta/TikTok/Reddit/gtag injection (default true)
engage: true, // surveys and promos (default true)
capturePageview: true, // initial $pageview (default true)
engagement: false, // scroll/time/rage-click/vitals/errors bundle (default false)
customLoader: false, // serve vendor scripts through your own domain (default false)
consentDefault: undefined, // "granted" | "denied" turns Consent Mode v2 on
productPathPrefixes: ["/products", "/categories"], // catalog_filter_applied scope
debug: false,
});| Option | Default | What it does |
|---|---|---|
apiKey | from the tag | Your site's key. Public by design; the backend checks your allowed origins |
host | see below | Where events are sent and where the lazy bundles are loaded from |
autocapture | true | Clicks, submits, pageviews, form abandonment and the data-pixelfox-* markup |
inventory | true | Auto-discovery of interactive elements |
remoteEvents | true | Match the event definitions from the dashboard |
vendorTags | true | Inject the pixels for the destinations connected in the dashboard |
engage | true | Fetch active surveys, promos and trigger rules once at boot. No DOM is touched until one fires |
capturePageview | true | Send $pageview on load and on SPA navigations |
engagement | false | Load the engagement bundle (see below). Also data-pixelfox-engagement="true" |
customLoader | false | Source every vendor script through the ingest host instead of the vendor's domain. Needs a custom ingest endpoint; turned on automatically once one is saved. Also data-pixelfox-custom-loader="true" |
consentDefault | off | "denied" seeds a default-deny before any tag loads (EU/EEA); "granted" turns Consent Mode on with everything allowed until your banner says otherwise. Omitted, Consent Mode stays off. Also data-pixelfox-consent-default |
productPathPrefixes | [] | Paths where a query-string-only navigation fires catalog_filter_applied |
debug | false | Log what the tag does to the console |
All feature flags except engagement, customLoader and consentDefault are
opt-out - everything else is on by default. engagement loads a second, lazy bundle
so the core tag stays inside its size budget.
How the host is chosen
- The
hostinit option. data-pixelfox-hoston the script tag.- On
localhostor127.0.0.1, the local development default. - The origin the script itself was loaded from. A tag served from
https://t.yourstore.com/pixelfox.min.jstherefore sends events tohttps://t.yourstore.comwith no further setup - this is how a custom ingest endpoint works.
If none of these yields a host the tag stays inactive and warns in the console.
Identifiers the tag keeps
| Key | Lives | Purpose |
|---|---|---|
pixelfox_did | localStorage + cookie, 1 year | The distinct id: anonymous until identify, then the user id |
pixelfox_device_id | localStorage + cookie, 1 year | The device id. Survives identify and reset, so a logout on a laptop is still that laptop. Only optOut removes it. Sent as $device_id on every event |
pixelfox_user_did | localStorage | The id passed to identify, remembered across visits |
pixelfox_super_props | localStorage | Super properties |
pixelfox_consent | localStorage | The Consent Mode state chosen by the visitor |
pixelfox_opt_out | localStorage + cookie | Set by optOut |
Every event also carries $timezone (the browser's IANA zone). Together with the
device id it lets PixelFox recognise a returning browser after its storage was cleared;
see identity and devices.
Reserved event names
$pageview, $identify, $create_alias, $groupidentify are emitted by the SDK
itself. Names starting with $ are reserved; use plain snake_case for your own events.
Auto-captured events
With autocapture on: $pageview, catalog_filter_applied, product_viewed,
section_viewed, image_load_failed, form_validation_error,
stock_status_displayed, form_abandoned, page_not_found, plus any event named by a
data-pixelfox-event attribute.
With engagement on, additionally:
| Event | Properties | When |
|---|---|---|
scroll_depth_reached | depth (25/50/75/100), pathname | first time each bucket is passed per page |
time_on_page | duration_ms, active_ms (tab visible), pathname | on leaving the page or an SPA navigation |
rage_click | tag, id, text, pathname | 3 clicks on one element within 800 ms |
dead_click | tag, id, text, pathname | a click on a non-interactive element that changed nothing within 1 s |
web_vitals | lcp, fcp, cls, inp, ttfb (ms; CLS unitless), pathname | once, when the page is hidden or unloaded |
$exception | message, source, line, stack, unhandled_rejection | uncaught errors and unhandled promise rejections |