Appearance
Installing the snippet
The snippet is a single script tag. Your dashboard's Setup instructions dialog shows it pre-filled with your tracking subdomain and client ID — and so does this page, once you've set your values from the top navigation:
html
<script async src="https://track.yourdomain.com/prism.js?id=cl_yourclient" data-cfasync="false"></script>Place it before the closing </head> tag on every page you want tracked. It loads asynchronously, so downloading the script does not block HTML parsing.
Payload size varies by capture profile and configuration. Measured on 12 September 2026 from generated snippets: approximately 12.5 KB gzipped for the Services profile and 26.4 KB gzipped for E-commerce. These are snapshot measurements, not a guarantee; check the browser Network panel for your deployed profile.
Keep data-cfasync="false"
If the site is behind Cloudflare with Rocket Loader enabled, this attribute stops Rocket Loader from deferring the script and breaking early click-ID capture. It's harmless everywhere else — leave it in.
Running an e-commerce store?
Shopify doesn't use this snippet at all — its checkout runs in a sandbox this script can't execute in. Follow the Shopify install guide instead, which uses a custom pixel built for that sandbox.
WooCommerce uses this same snippet — install it as above — plus two order webhooks for reliable purchase totals. See the WooCommerce install guide.
Every other platform uses this same snippet, and gets the full e-commerce event journey — cart, checkout steps, purchases — for free if the site already has GA4/Google Tag Manager e-commerce tracking. See Detecting e-commerce with dataLayer for how that works.
Remove existing Meta pixel installs
If the site already runs a Meta pixel — hardcoded base code, the Meta WordPress plugin, or a Custom HTML tag in Tag Manager — remove it when Prism's Meta CAPI connection goes live. A legacy pixel running alongside Prism double-counts events and can carry hidden browser-side rules (Meta's Event Setup Tool) that fire events no code on the site explains. Removing it costs nothing: Prism generates the _fbp browser ID itself.
Full checklist of where pixels hide and how to verify removal: Meta CAPI → Remove existing pixel installs first.
What it does on load
- Captures ad click IDs from the URL (
fbclid,gclid,ttclid, and others) into 90-day first-party cookies. - Fetches a server-issued identity (
adsidian_id, an HTTP-only cookie that lasts 1 year). - Fires an automatic
PageViewevent. - Captures UTM parameters on every event.
Platform guides
WordPress
- With a theme that supports header scripts (Astra, GeneratePress, …): Appearance → Customize → Header scripts (naming varies), paste the tag.
- Any theme: install a header/footer script plugin (e.g. WPCode), add the tag to the header section, site-wide.
- WordPress.com (Business/Commerce): Tools → Marketing → Traffic or a header-script plugin as above.
Shopify
Don't use this snippet — see the dedicated Shopify install guide, which uses a custom pixel built for Shopify's checkout sandbox.
Webflow
Site settings → Custom code → Head code, paste, publish.
Google Tag Manager
Prefer a direct install when possible (GTM adds a loading layer that ad blockers target). If GTM is the only option: create a Custom HTML tag with the snippet, trigger on All Pages — Page View, and enable Support document.write off (not needed).
Plain HTML / other CMS
Paste into the shared header template so it renders on every page.
Single-page applications
The snippet fires PageView once per full page load. For client-side route changes in a SPA, fire a manual page view on navigation:
js
window.prism('track', 'PageView');Privacy & consent
Prism is built to honour visitor privacy signals on its own. You do not need to gate the snippet to be consent-correct, though you can (see Optional stricter install below and the Consent integration page).
Signals Prism honours
Global Privacy Control. If the browser sends
Sec-GPC: 1or exposesnavigator.globalPrivacyControl, the visitor's events are stored first-party and never forwarded to ad platforms. The server checks theSec-GPCheader itself, so this holds even if a payload claims consent. GPC only ever denies; it can't be overridden by a consent grant.Consent managers (non-Shopify sites). Tell Prism the visitor's choice any of four ways; the latest signal wins, and an explicit denial suppresses ad-platform delivery:
window.prismConsent, read at load and re-read on every event send (only changed keys are merged).- The
prism('consent', {...})command, available onceprism.jshas loaded. - A
prismConsentDOMCustomEventonwindowordocument, with the same object asdetail. - IAB TCF v2: Prism subscribes via
__tcfapi('addEventListener', …)and updates ontcloadedanduseractioncomplete. TCData withgdprApplies === falseis ignored.
js// Each key is 'granted' or 'denied'; partial objects are fine. prism('consent', { ad_storage: 'denied', ad_user_data: 'denied', ad_personalization: 'denied', analytics_storage: 'granted', }); // Or, without calling into Prism: window.dispatchEvent(new CustomEvent('prismConsent', { detail: { ad_storage: 'granted', ad_user_data: 'granted', ad_personalization: 'granted' }, }));GPC and Shopify denials always win over any of these. While ad consent is denied,
_fbpisn't created, and it stops being sent if consent is denied after the page loaded. Details: Consent integration.Shopify Customer Privacy API. On Shopify storefronts,
prism.jsreadswindow.Shopify.customerPrivacy. IfmarketingAllowed()orsaleOfDataAllowed()returnsfalse, ad consent is denied, and it re-reads when the visitor changes their choice (thevisitorConsentCollectedevent). This is denial-only: a missing API is ignored, and a later grant restores delivery.No signal at all. The per-client
consent_defaultapplies. In the US the default isgranted; clients that need explicit opt-in can set it todenied. See Consent integration.
"Denied" never means "dropped": the event is still stored in your own first-party records, with its consent status, so your analytics keep working.
Server-side order records (such as Shopify or WooCommerce order webhooks) have no browser consent signal of their own, so a purchase arriving by webhook inherits a browser opt-out when it can be linked to the shopper's browsing: by the cart or checkout token, or by Prism's own visitor ID (adsidian_id). It is never linked by email address, so a Global Privacy Control opt-out on one device doesn't deny a purchase made on another. If any linked cart carries a denial, the order is withheld from ad platforms (it is still stored in your own records). An order that can't be linked to an opted-out session may still be forwarded to the platforms you enable.
Cookies and storage
| Cookie | Lifetime | Purpose | When it is set |
|---|---|---|---|
adsidian_id | 1 year, HTTP-only | First-party visitor identity, issued by your tracking subdomain | When the snippet initializes |
_prism_fbclid, _prism_gclid, _prism_ttclid, _prism_li_fat_id, _prism_ScCid, _prism_rdt_cid, _prism_oppref | 90 days | First-party click-ID attribution | Only when that click ID is in the landing URL |
_fbp | 90 days | Meta browser ID for Conversions API matching | Only when ad consent is not denied. When denied it is neither created nor sent |
_prism_aid | Set by Shopify's cookie API | Visitor identity inside the Shopify checkout sandbox | Shopify custom pixel only |
Browsers can shorten these lifetimes. See Customer data & privacy.
What form auto-capture reads
On submit, Prism reads from forms that have an email or phone field: email, phone, first name, last name, city, state, ZIP and date of birth, when present. Values are trimmed, capped at 200 characters and SHA-256 hashed in the browser before sending. You can turn off phone capture for a site in Prism Setup → Event settings. Password and search forms, and hidden, file, checkbox and radio inputs, are never read.
Excluding a form: data-prism-ignore
Add data-prism-ignore to a form, or to any ancestor of it, to exclude it entirely: no field capture, and no FormSubmit, Lead, FormEngage or FormAbandon events from that form.
html
<form data-prism-ignore> ... </form>
<div data-prism-ignore><form> ... </form></div>To still count a conversion without capturing any form data, put data-prism-event on the element instead; it fires the named event with no form data. Use data-prism-ignore for forms that collect sensitive information (health, financial, or similar), and never pass such data in event properties.
Retention, IP addresses and deletion
- Retention. Raw event data is kept for 395 days (about 13 months) by default and purged daily. The window is configurable per client.
- IP addresses are truncated before storage by default (the last IPv4 octet, or the last 80 bits of an IPv6 address, is zeroed).
- Deletion requests are handled by anonymizing the matching records. Data already delivered to Meta, Google, LinkedIn, Reddit or OpenAI stays with them; point visitors to those platforms' own controls.
Optional stricter install: load prism.js only after consent
prism.js already honours the signals above, so this is optional. Use it if your policy requires that no Prism cookie or request happens before consent. The trade-off: visitors who haven't consented get no first-party analytics either.
For Shopify themes (see Installing on Shopify), place this in theme.liquid before </head>, in place of the plain script tag. It loads prism.js only when marketing and sale-of-data are both allowed and Global Privacy Control is off, and checks again when the page finishes loading and whenever the visitor answers the consent banner. If Shopify.customerPrivacy doesn't exist on the page, it loads nothing:
html
<script>
(function () {
var SRC = 'https://track.yourdomain.com/prism.js?id=cl_yourclient';
var loaded = false;
function gpcOn() {
return navigator.globalPrivacyControl === true;
}
function consentOk() {
var cp = window.Shopify && window.Shopify.customerPrivacy;
if (!cp || typeof cp.marketingAllowed !== 'function' ||
typeof cp.saleOfDataAllowed !== 'function') return false;
return cp.marketingAllowed() === true && cp.saleOfDataAllowed() === true;
}
function load() {
if (loaded) return;
loaded = true;
var s = document.createElement('script');
s.async = true;
s.src = SRC;
s.setAttribute('data-cfasync', 'false');
document.head.appendChild(s);
}
function check() {
if (!gpcOn() && consentOk()) load();
}
// Ask Shopify to load the Customer Privacy API (its documented way), then
// evaluate. The checks below are extras: now, again once the page has
// loaded (the API can arrive late), and whenever the visitor answers the
// cookie banner. If the API never appears, nothing loads.
if (window.Shopify && window.Shopify.loadFeatures) {
window.Shopify.loadFeatures(
[{ name: 'consent-tracking-api', version: '0.1' }],
function (err) { if (!err) check(); }
);
}
check();
window.addEventListener('load', check);
document.addEventListener('visitorConsentCollected', check);
})();
</script>Test in the theme preview
Paste the loader into a duplicate or previewed theme first. With the browser's Network panel open, confirm prism.js is not requested before you accept the cookie banner, loads after you accept, and does not load when Global Privacy Control is on.
Once loaded, prism.js keeps reading the same signals itself, so a later denial still stops ad forwarding. For non-Shopify sites, use the same pattern with your consent manager's callback; see Consent integration.
Telling your visitors
Your privacy notice must disclose Prism's cookies, the fields it captures, and the sharing with ad platforms. See Suggested privacy-policy wording for text you can adapt.
Next
- Verify your install
- Suggested privacy-policy wording
- Track custom events
- E-commerce events, if you're tracking a store