Facebook Pixel - Custom Tag Template for Google Tag Manager.
by facebookSmarty
Last 12 weeks · 18 commits
4 of 6 standards met
Environment Google Tag Manager Official Meta Pixel Community Template (latest, v. d7103) Magento 2 RequireJS (AMD) Issue After adding a standard Meta Pixel tag (PageView) using the official GTM template, Magento throws the following console error: Additionally: Investigation The issue is caused by the following script loaded by the template: The bundle contains the following UMD wrapper: Since Magento 2 uses RequireJS, the bundle registers itself as an anonymous AMD module, resulting in: Reproduction 1. Install the latest Meta Pixel GTM Community Template. 2. Create a basic PageView tag. 3. Preview or publish the container on a Magento 2 website. 4. Open the browser console. Additional information The issue occurs regardless of whether the following options are enabled or disabled: Advanced Matching GA4 dataLayer Integration Enhanced Ecommerce Integration Meta-enabled Conversions API Integration Automatic Configuration History Event Tracking Workaround Removing the injection of: from the template immediately resolves the issue. Results: No more errors. No more errors. The Meta Pixel continues to fire correctly. This appears to be a compatibility issue between and RequireJS environments such as Magento 2. We've also received reports that this issue may affect Knockout-based Magento components (e.g. the mini cart), although we have not yet been able to consistently reproduce this behavior ourselves.
Template: Meta Pixel (official GTM Web template) Version: 2.0.8 (agent string tmSimo-GTM-WebTemplate-2.0.8) Environment:** GTM Web container, Chrome, Tag Assistant connected Summary With Advanced Matching configured, the template logs (fbevents.js:184) on the first fire and on every subsequent fire. fbq('init', , cidParams) is called more than once per pixel within a single tag execution. Root cause Three init paths target the same pixel and de-duplication is incomplete: 1. First-init loop () inits once, pushes the ID into the local array, and sets . 2. The re-init block is gated only on: . Its comment states it should also require that no pixel was yet initialized with cidParams, but is never read. The flag is dead code. Because path 1 pushes the ID into the same local before this block runs, the re-init also fires on the very first execution, not only later ones. 3. The GA4 gate callback ( + ) merges user data into cidParams and inits again with no init-once guard. Net effect: up to 3 init calls on the first fire and 2 per subsequent fire for a GA4 ecommerce + Advanced Matching + user_data configuration. Expected One init per pixel per page lifecycle; later fires reuse the registered pixel and only re-init once if cidParams first become available after an init without them. Actual Repeated init for an already-registered pixel, producing Duplicate Pixel ID warnings. Events are not duplicated; impact is console noise during QA and prod debugging. Steps to reproduce 1. Configure the tag with Advanced Matching (one or more cidParams). 2. Fire any standard event. Observe the warning on the first fire. 3. Fire a second event on the same page. Warning repeats. 4. With GA4 Ecommerce enabled and user_data in eventModel, the count increases.
Summary When a tag using Advanced Matching fires for the first time on a page, the template initializes the same Pixel ID twice in a single tag fire, which causes to log: This happens even when the user has exactly one Meta Pixel tag firing exactly once. The duplicate is internal to the template. Template version: (agent string in ). Root cause The sandboxed JS has two paths that both run during the same execution. is read once from the window and is the array the re-init block later checks: https://github.com/facebook/GoogleTagManager-WebTemplate-For-FacebookPixel/blob/6fc3e0dd5a9b7ae6f92910c3c6810e36cd9277d4/template.tpl#L513 Block 1 — first-time init. Note it calls and then es the pixel into the very same array: https://github.com/facebook/GoogleTagManager-WebTemplate-For-FacebookPixel/blob/6fc3e0dd5a9b7ae6f92910c3c6810e36cd9277d4/template.tpl#L621-L659 Block 2 — re-init with . Its guard is : https://github.com/facebook/GoogleTagManager-WebTemplate-For-FacebookPixel/blob/6fc3e0dd5a9b7ae6f92910c3c6810e36cd9277d4/template.tpl#L661-L672 On a first fire with Advanced Matching: 1. starts empty, so Block 1's is true → runs, then mutates the array. 2. Block 2 then checks , which is now true (Block 1 just pushed it) → runs again, with the same . Two calls for the same ID with identical advanced-matching data in one fire → emits Duplicate Pixel ID. The core problem is that Block 1 mutates before Block 2 reads it, so Block 2 cannot distinguish "initialized on a prior fire" from "initialized just now in this same fire." Why the existing tests don't catch it The unit tests for the re-init block all pre-seed with the pixel IDs (i.e. they only simulate a subsequent fire, where Block 1 is skipped), so the first-fire double-init never occurs in the tests: — https://github.com/facebook/GoogleTagManager-WebTemplate-For-FacebookPixel/blob/6fc3e0dd5a9b7ae6f92910c3c6810e36cd9277d4/template.tpl#L1641-L1671 — https://github.com/facebook/GoogleTagManager-WebTemplate-For-FacebookPixel/blob/6fc3e0dd5a9b7ae6f92910c3c6810e36cd9277d4/template.tpl#L1693-L1723 There is no test for the case " empty and non-empty", which is exactly the buggy path. Note: dead flag + stale comment Block 1 sets (L653–L657) but nothing ever reads it, and the comment above Block 2 ("we have NOT yet initialized any pixel with cidParams on this page") describes a guard that isn't implemented — and which would actually contradict the test. This looks like the leftover of an earlier "only once per page" design that was superseded by "re-init on every subsequent fire." The fix below keeps the tested "every subsequent fire" behavior; the dead and stale comment can then be removed. Reproduction 1. One Meta Pixel tag with a Pixel ID and at least one Advanced Matching parameter configured. 2. Load a fresh page (so is unset) and fire the tag once. 3. Observe in the console. Suggested fix Track which pixels are initialized during this fire, and have the re-init block skip those (only refresh pixels initialized on a prior fire). This removes the first-fire duplicate while preserving the "re-init on every subsequent fire" behavior asserted by the existing tests. This keeps all current tests green: First fire ( empty): Block 1 inits once with ; Block 2 skips (pixel is in ) → no duplicate. Subsequent fire ( pre-seeded): Block 1 skips; is empty, so Block 2 re-inits as before. A worthwhile addition would be a test covering the first-fire-with-Advanced-Matching path that asserts is called exactly once per Pixel ID. Related: GA4 Ecommerce path The GA4 Ecommerce branch has the same shape — it calls again, in addition to Block 1's first-time init, within the same fire: https://github.com/facebook/GoogleTagManager-WebTemplate-For-FacebookPixel/blob/6fc3e0dd5a9b7ae6f92910c3c6810e36cd9277d4/template.tpl#L688-L713 Because this path also enriches from , the cleanest fix is to assemble the final (advanced matching + GA4 ) before a single , rather than init-then-reinit. At minimum it should avoid re-initializing a pixel that was just initialized in the same fire. Happy to follow up on this part separately if the maintainers prefer.
Purpose This PR introduces version 2.0.8, adding explicit fallback protections for Google Consent Mode v2 frameworks. Key Changes Added SHA representing v2.0.8. Automatically bridges GTM and states directly to Meta's Limited Data Use (LDU) / Data Processing Options flags if explicit consent data is missing or denied. Enhances regulatory compliance for enterprise deployments targeting users in the EU/EEA without breaking existing standard configurations.
Repository: facebook/GoogleTagManager-WebTemplate-For-FacebookPixel. Description: Facebook Pixel - Custom Tag Template for Google Tag Manager. Stars: 52, Forks: 33. Primary language: Smarty. Languages: Smarty (100%). License: Apache-2.0. Open PRs: 2, open issues: 20. Last activity: 2w ago. Community health: 75%. Top contributors: chc421, facebook-github-bot.