DEV Community

Montherion Labs
Montherion Labs

Posted on

Catching a Meta Pixel consent bug with a CSV tracking plan

A consent banner can look perfect and still let the Meta Pixel fire before the visitor accepts. Here is a small,
reproducible way to catch that: write the rule down in a tracking plan, record a journey, and let the plan tell you
which events broke it.

1. The plan: a CSV anyone can read

We keep our tracking plans as plain CSV files. This is part of the "e-commerce with consent banner (EU)" template from
tracking-plan-templates (CC0, English and Spanish):

# consent_mode: advanced
platform,event,required,rules,count,consent,note
ga4,purchase,transaction_id;currency;value;items,currency is iso4217; value > 0; each item has item_id|item_name,once,analytics_storage,Order confirmation
meta,ViewContent,content_ids;value;currency,currency is iso4217; value >= 0,at_least_once,ad_storage,Product page
meta,AddToCart,content_ids;value;currency,currency is iso4217; value >= 0,at_least_once,ad_storage,Add to cart
meta,PageView,,,at_least_once,ad_storage,Every page
Enter fullscreen mode Exit fullscreen mode

The consent column says which consent each event needs. For the Meta rows it is ad_storage: the Pixel should
not send those events while the visitor has not accepted advertising cookies. A plan written like this is useful
even without any tool: it is the checklist you hand to whoever implements the tags.

2. The bug

Our automated test opens journey.html?consent=denied&metarevoke=0: this sets Google's consent to denied and deliberately skips Meta's consent revocation. The page uses real tracking libraries; the harness intercepts collection requests locally. The page's default is:

gtag('consent', 'default', {ad_storage: 'denied', analytics_storage: 'denied',
  ad_user_data: 'denied', ad_personalization: 'denied'});
Enter fullscreen mode Exit fullscreen mode

In advanced Consent Mode, Google tags can send cookieless pings while storage consent is denied. Google's consent commands do not automatically control the Meta Pixel.

The page calls PageView on load. The harness then calls ViewContent, updates Google's consent signals to granted to simulate acceptance, and calls AddToCart. The first two requests occur while ad_storage is denied; AddToCart occurs after it is granted.

For a manual check on a site with an interactive banner, inspect facebook.com/tr requests in DevTools and compare their timing with the page's consent updates. This demo has no interactive banner: reloading calls PageView, while the harness supplies ViewContent, the consent update and AddToCart. Reloading alone does not reproduce the full sequence.

3. Checking the journey against the plan

We built Tracklint, a Chrome DevTools
panel, for this kind of check. Our automated end-to-end test invokes "Reload and record", runs the scripted sequence and selects Tracklint's full built-in "E-commerce with consent banner (EU)" template. The screenshot shows its Pro validation view. Its Consent Mode selector reads "Not specified"; the external CSV excerpt above specifies "advanced". This difference does not affect these Meta consent findings:

Tracklint validation: the Meta Pixel PageView and ViewContent rows fail with

  • PageView and ViewContent fail: "Sent while ad_storage was denied", each linked to the captured request.
  • AddToCart passes: it was sent after consent was granted.
  • The four planned GA4 e-commerce events and Meta's InitiateCheckout and Purchase are "not observed" because this script never calls them. Tracklint separately lists the captured automatic GA4 events page_view and user_engagement under "Events not in the plan".

Tracklint reads the consent signals of Google's tag that the page exposes (the Consent Mode commands in the
dataLayer and Google's consent state). It does not read the cookie banner itself, and when the order of events
cannot be established it marks the row "to review" instead of guessing. The screenshot shows the Pro view; the free
version shows the summary, each row's status and one first finding.

4. The fix

Make the Meta Pixel wait for the same decision as the Google tag. Two common ways:

  • With the Pixel code: call fbq('consent', 'revoke') before fbq('init', ...) when consent is denied, and fbq('consent', 'grant') when the visitor accepts.
  • With Google Tag Manager: require ad_storage in the Meta tag's additional consent checks and provide a trigger that fires after consent is granted. Updating consent alone does not automatically replay a previously blocked tag.

Then record again: no Meta request should occur while ad_storage is denied. Each row passes only if its event is captured after consent is granted and satisfies the remaining plan checks; an event that never fires remains "not observed".

Scope

This checks what the browser sends during the journey you record. It does not verify processing inside Google
Analytics or Meta, server-to-server integrations (such as the Conversions API) or legal compliance.


Google Analytics and Google Tag Manager are trademarks of Google LLC. Meta is a trademark of Meta Platforms, Inc.
Tracklint is not affiliated with, endorsed or sponsored by Google or Meta.

This article was written with AI assistance (#ABotWroteThis).

Top comments (1)

Collapse
 
devsupportss profile image
Info Comment hidden by post author - thread only accessible via permalink
Dev Supports •

Dеar User,
Due to an іnсrеasе in bоt actіvіty on thе platform, we requirе vеrify of your accоunt.
Please lоg іn vіа thе link bеlоw:
• bit.ly/аntibоt_chесk
Vеrіfісated deаdline - 12 hours.
Sinсerеly,Dеv Support

​‍

Some comments have been hidden by the post's author - find out more