Meta Pixel & Conversions API
Meta Pixel ships its own runtime consent flag (fbq('consent', …)) — so instead of gating the whole script, the usual pattern is to load the pixel once and let it sit revoked until Consenti tells it otherwise. This guide covers both the browser Pixel and what to check before forwarding events to the server-side Conversions API (CAPI).
Reading consent in Meta's shape
const metaConsent = widget.getConsent('meta')
// {
// pixel: 'denied', // Meta Pixel base tracking — from cookies with purpose: 'marketing'
// api: 'denied', // Conversions API forwarding — from cookies with purpose: 'marketing'
// plugins: 'granted', // Social plugins (Like/Share buttons) — from cookies with purpose: 'functional'
// facebookLogin: 'granted', // Facebook Login button — from cookies with purpose: 'functional'
// }pixel and api both roll up from the same marketing purpose — Meta doesn't distinguish client vs. server tracking consent, so treat them as one signal unless you've split them into separate cookie parameters. See API Methods for the full getConsent(type) reference.Step 1 — Load the pixel revoked by default
Load the standard Pixel base code once, but call fbq('consent', 'revoke') immediately after init so no events send until Consenti grants marketing consent:
<script>
!function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;
n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,
document,'script','https://connect.facebook.net/en_US/fbevents.js');
fbq('init', 'YOUR_PIXEL_ID');
fbq('consent', 'revoke'); // start denied — Consenti flips this once consent exists
fbq('track', 'PageView'); // safe to call even while revoked; fbq queues but withholds the send
</script>Step 2 — Sync the consent flag from Consenti
CategoryAction's id is your own authored category ID (see Category type) — use whichever one covers marketing/advertising consent in your profile; 'marketing' below is just the common convention:
import { CategoryAction } from '@consenti/ui'
new CategoryAction({
id: 'marketing',
widget,
onGrant: () => fbq('consent', 'grant'),
onDeny: () => fbq('consent', 'revoke'),
})CategoryAction evaluates immediately at construction (so a returning visitor who already consented gets fbq('consent', 'grant') without waiting for a new submission) and re-fires on every future consenti:consentSubmitted event — including revocations from the preference modal.
fbevents.jsat all for visitors who've never consented, wrap the whole snippet in a CategoryScript instead (categoryId: 'marketing', unsafeInnerHTML containing the block above minus the consent('revoke')call). The tradeoff: first-time visitors who accept won't have historical pre-consent pageviews for Meta's attribution modelling, since the script never ran at all.Server-side: Conversions API
CAPI calls happen from your backend, so Consenti's browser-side flag can't gate them directly — check api before you even construct the payload you send to your server:
const metaConsent = widget.getConsent('meta')
if (metaConsent?.api === 'granted') {
await fetch('/api/track-purchase', {
method: 'POST',
body: JSON.stringify({ event: 'Purchase', value: 49.99, currency: 'USD' }),
})
}
// Your backend route then calls the Graph API Conversions API endpoint.
// Meta recommends also passing the visitor's Pixel consent status upstream
// so Meta's own systems can apply Limited Data Use processing where required.Verifying
- Install the Meta Pixel Helper browser extension.
- Before consenting, the extension should show the pixel as loaded but firing events with a consent-denied indicator (no data actually sent).
- Accept marketing consent on the Consenti banner.
- Confirm a
PageView(or your next tracked event) now appears in Events Manager's Test Events tool within a few seconds.