Tag the Meta Pixel code with the targeting category of Cookie Consent, or load the pixel with fbq('consent', 'revoke') and send fbq('consent', 'grant') from the scripts_specific_loaded callback. Both setups stop the pixel from sending events to Meta until the visitor accepts advertising cookies. The Meta Pixel sets advertising cookies and sends page views and conversions to Meta, so the ePrivacy Directive and PECR require consent before it runs. Set up either approach in about 10 minutes.

What happens on your site with the Meta Pixel

The Meta Pixel loads fbevents.js from connect.facebook.net, stores its cookies on your domain, and sends each event to www.facebook.com/tr. The base code Meta gives you does all 3 on every page load, before any visitor answers the consent banner.

Compare what each approach lets the pixel do before and after the visitor accepts.

Approach Before the visitor accepts After the visitor accepts
Approach 1: tag the pixel No request to Meta, no cookie The pixel loads and sends the page view, with no page reload
Approach 2: load the pixel and send the Meta consent commands fbevents.js loads from connect.facebook.net; Meta pauses the events Events called after the callback sends grant reach Meta

The targeting category controls the Meta Pixel. Check every signal the category sets in Map Categories to Vendor Consent Signals.

Approach 1: Tag the Meta Pixel code

Change the opening tag of the pixel script to <script type="text/plain" data-cookie-consent="targeting"> and delete the <noscript> image. The browser does not run a text/plain script, so the pixel waits. Cookie Consent runs it the moment the visitor accepts targeting, and on every later page load of a visitor who accepted.

Replace YOUR_PIXEL_ID in this tagged base code with the pixel ID from Meta Events Manager. Keep the block in <head>, as Meta asks. The tagged block works from the <body> too, because Cookie Consent reads tagged scripts when run() starts, which the generator code delays until the browser has read the whole page.

<!-- Meta Pixel Code, held by Cookie Consent -->
<script type="text/plain" data-cookie-consent="targeting">
  !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('track', 'PageView');
</script>
<!-- End Meta Pixel Code -->

Tag every other script that calls fbq, such as a fbq('track', 'Purchase') on your order confirmation page, with targeting. Cookie Consent runs tagged scripts of one category in page order, so the event script runs after the base code. Learn how tagged scripts run, and in which order, in Block Scripts Until Consent.

Keep the pixel untagged, add fbq('consent', 'revoke') before fbq('init'), and send fbq('consent', 'grant') from scripts_specific_loaded when Cookie Consent releases targeting. Meta pauses pixel events while consent is revoked, according to the Meta developer page "General Data Protection Regulation". Meta asks for the revoke call before fbq('init') and on every page, so keep it in the base code.

Keep this base code with the revoke command untagged in <head>.

<!-- Meta Pixel Code, consent revoked until the visitor accepts -->
<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('consent', 'revoke');
  fbq('init', 'YOUR_PIXEL_ID');
  fbq('track', 'PageView');
</script>
<!-- End Meta Pixel Code -->

Keep every other script that calls fbq, such as a fbq('track', 'Purchase') on your order confirmation page, untagged and below the base code. The revoke command pauses those events like the page view.

The callback sends grant for targeting, and "callbacks_force": true makes it run even though no script carries the targeting tag. With callbacks_force, the callback runs once for each released category on every page load of a visitor who accepted, and after each answer that accepts targeting. Add callbacks and callbacks_force to your run() call, beside the options the TermsFeed generator writes.

"callbacks": {
  "scripts_specific_loaded": function (level) {
    switch (level) {
      case 'targeting':
        if (typeof window.fbq === 'function') {
          window.fbq('consent', 'grant');
        }
        break;
    }
  }
},
"callbacks_force": true

The callback only grants consent, so the revoke command in the base code covers a visitor who declines. A visitor who withdraws targeting gets the revoke again from the next page load. Read every moment the callback runs in When scripts_specific_loaded Needs callbacks_force.

Approach 2 sends the IP address of every visitor to Meta, because the browser downloads fbevents.js from connect.facebook.net before the visitor answers. Choose Approach 1 where your legal advice treats that request as needing consent.

Meta Limited Data Use (fbq('dataProcessingOptions', ...)) is a separate Meta setting for some US states, according to the Meta developer page on data processing options. It does not replace the revoke and grant commands.

The checks assume express consent with page_load_consent_levels left out or at the generator value ["strictly-necessary"], and the "I decline" button shown. Publish the change and clear any page cache before the check. Close every private window and open a new one before the check, so no earlier answer hides the consent banner. On a working page, no event reaches Meta before you accept.

  1. Open Chrome DevTools, select the Network tab, type facebook in the filter box, and open your site. With Approach 1, no request appears. With Approach 2, a request to connect.facebook.net appears, and no request to facebook.com/tr does.
  2. With Approach 1, select the Application tab, open Cookies, and select your domain. No _fbp cookie exists yet, because the pixel code has not run. Meta documents only that the revoke command holds events and says nothing about cookies, so skip this step with Approach 2.
  3. Select the Network tab again and click the "I agree" button. With Approach 1, confirm that a request to facebook.com/tr with ev=PageView in its URL appears at once, with no page reload. With Approach 2, Meta does not document whether it sends the page view it paused. Run fbq('track', 'PageView') in the Console and confirm that a request to facebook.com/tr with ev=PageView appears.
  4. Close every private window and open a new one. Open DevTools, type facebook in the Network filter, load your site, click the "I decline" button, and open a second page. Confirm that no request to facebook.com/tr appears, on the page where you declined or on the second page.

Cookies the Meta Pixel sets

The Meta Pixel stores 2 first-party cookies on your domain: _fbp, a browser identifier, and _fbc, the ad click identifier. Meta writes _fbp when the pixel runs. Meta writes _fbc when a visitor arrives from a Facebook or Instagram ad with a click ID in the address. Both facts come from the Meta developer page on the fbp and fbc parameters.

Neither approach deletes these cookies once they exist. A visitor who accepted and later withdraws keeps the _fbp cookie until it expires. Delete the _fbp and _fbc cookies from a callback with the pattern in Rejecting Does Not Delete Cookies Already Set.

Common mistakes with the Meta Pixel

Start from what the Network tab shows. A Meta request before the answer comes from code Cookie Consent does not hold, and a missing event after it comes from event code or a callback that never runs. Search your page source and your platform integrations for each mistake.

  • The <noscript> image stays in the page. The image fires only for visitors with JavaScript turned off, who never see the consent banner, so it sends a page view to Meta with no consent. Your own check with JavaScript on never shows that request. Search the page source for <noscript> near the pixel code. Delete the whole <noscript> block Meta supplies.
  • A platform or a plugin adds a second copy of the pixel. A pixel added through a Shopify app, a WordPress plugin, or a tag manager runs outside Cookie Consent. Search the page source and your tag manager container for your pixel ID to find each copy. Remove that integration and keep the copy you tagged.
  • Event code runs untagged in Approach 1. An untagged fbq('track', ...) call runs before the tagged base code defines fbq, so it fails with a ReferenceError in the Console, and Meta never receives the event. Tag every script that calls fbq with targeting.
  • The pixel is tagged with tracking. A visitor who turns on only the switch of the "Tracking cookies" tab in the Preferences Center then gets the Meta Pixel, an advertising tool, without accepting targeting. Look for data-cookie-consent="tracking" on the pixel scripts, and change it to targeting.
  • Approach 2 lacks callbacks_force. On a page with no script tagged targeting, the grant never runs, so after you accept, running fbq('track', 'PageView') in the Console does not send a request to facebook.com/tr. Add "callbacks_force": true to the run() options.
  • The Meta Conversions API sends events from your server. Meta then receives server events from visitors who declined, because no consent banner stands between your server and Meta. Check that your server code reads the cookie_consent_level cookie before each event, and send events only for visitors whose targeting category reads true.

Server events and <noscript> images skip the consent banner for every vendor, not only for Meta. Read the reason for each route in Why server-side event sending bypasses the consent banner and Why vendor noscript fallbacks stay out of the page.