Facebook Pixel firing twice: one pixel, one init
Conversion tracking on a 2016 marketplace launch, the Facebook Pixel firing twice that inflated our numbers, and Google Analytics beacon transport.
From 2016 · 2 min read · Published August 26, 2026
In the fall of 2016 I was shipping a two-sided rental marketplace: an iOS app, a web app, a marketing site on WordPress, and a versioned API documented with apidoc (users, renters, vehicles, bookings). The app went to the App Store as a release candidate in early October. Then the real work started: figuring out whether any of the marketing was working, which is where we found our Facebook Pixel firing twice.
That meant conversion tracking across all of it. Facebook pixel and app events, Google Analytics, Segment, and Firebase on iOS, all in the span of about three weeks of commits.
The bug: duplicate Facebook Pixel events
On November 12th and 13th the history reads "fb events," "fixing events," and then "fixing duplicate pixel."
The signup modal's script initialized the Facebook pixel on page load. The signup success handler initialized it again before tracking the Lead event. Pixel code tolerates being initialized twice without errors, which is exactly why this kind of bug survives: nothing breaks. You just get duplicate PageViews, inflated counts, and conversion rates that look better than they are.
The fix was to delete the page-load init and leave one place that owns it:
jQuery(window).load(function() {
// if (window.location.hostname.toLowerCase().indexOf('www.example.com') > -1) {
// fbq('init', '...');
// fbq('track', 'PageView');
// }
initValidation();Send events that survive navigation
A few days earlier I'd added a Google Analytics event on signup clicks. The detail worth copying is the transport:
ga('send', 'event', {
eventCategory: 'signup',
eventAction: 'click',
eventLabel: e.target.href,
transport: 'beacon',
})A click that navigates away can kill the page before a normal analytics request finishes. transport: 'beacon' uses navigator.sendBeacon, which the browser completes even as the page unloads. Without it, you undercount exactly the clicks you care most about: the ones that lead somewhere.
What I'd tell a team launching today
- One owner per tracker. Initialize each analytics library in exactly one place. Grep for
initbefore every launch. - Duplicates don't error. Test tracking by watching the network tab or the vendor's debugger, not by waiting for the dashboard.
- Use beacon-style delivery for any event fired right before navigation.
- Decide your source of truth. With four tools reporting four slightly different numbers, pick the one you'll make decisions on, and treat the others as diagnostics.
Related: Build a monitor, not a dashboard: the Cloudflare Zaraz false negative · Regex anchors, and three commits to validate one IDFA