Rangi Lin
Rangi Lin

Reputation: 9461

Will it cause any issue if I use multiple Facebook Pixel in one page?

I would like to include both my Facebook Pixel id and customer's Facebook Pixel id in one page, so both of us can have some insight about users, and customer can also create ADs for the page if he or she wants to.

I already test tracking and it seems to work fine. However I do receive warnings from Pixel SDK about "Multiple different pixels were detected on this page".

Since I cannot find any information about this scenario, I would like to know whether it is okay to do so ?

Thanks

Upvotes: 31

Views: 52137

Answers (6)

Julien Bachmann
Julien Bachmann

Reputation: 792

I had the same requirement and I found that it is possible and you don't need to hack the Facebook pixel code.

Even if it is not documented, the fbq object support multiple pixel ids.

Just call multiple times the init function with different pixel ids. Then, then when you do fbq('track', "PageView"); it will issue one event per pixel. You can call fbq('track', '{{your_event_name}}')as many times as you want and it will track the event for all previously initialized pixels.

So your final code would look like this:

<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','//connect.facebook.net/en_US/fbevents.js');
    fbq('init', '{{pixel_id_1}}');
    fbq('init', '{{pixel_id_2}}');
    fbq('track', "PageView");
</script>
<noscript>
  <img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id={{pixel_id_1}}&ev=PageView&noscript=1" />
  <img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id={{pixel_id_2}}&ev=PageView&noscript=1" />
</noscript>

Edited April 2019 @chuck-le-butt found that a blog post from facebook document how to use the pixel: https://developers.facebook.com/ads/blog/post/2017/11/28/event-tracking-with-multiple-pixels-tracksingle/

Upvotes: 28

John Washam
John Washam

Reputation: 4103

Having multiple pixels on your site shouldn't create any issues on your site itself (i.e. there won't be JavaScript errors, and all events will be sent for all the initialized pixel IDs). I wrote a blog post about this issue, so feel free to read there for a more full discussion.

After including the full Facebook pixel code snippet once on the site, you can then simply add additional pixel ID inits before calling any track events. So your full pixel code snippet on the site would look like this:

<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','//connect.facebook.net/en_US/fbevents.js');
    fbq('init', '[first-pixel-id]');
    fbq('init', '[second-pixel-id]');
    fbq('track', 'PageView');
</script>
<noscript>
    <img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=[first-pixel-id]&ev=PageView&noscript=1" />
    <img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=[second-pixel-id]&ev=PageView&noscript=1" />
</noscript>

Once you have initialized all the pixel IDs on your site with fbq('init'), you can confirm they have been loaded by running the following code in the JavaScript console:

fbq.getState().pixels

You should also install the Facebook Pixel Helper. It gives some detailed information about each pixel and each track event sent to Facebook.

The next natural question is how to track events to only one of those pixel IDs. If you're handling a product catalog for Facebook Dynamic Ads, you may need to track events and pass Facebook your unique product ID for the product on the site.

As of late 2017, Facebook finally announced functionality to track pixel events to single pixel IDs. You simply use the actions trackSingle and trackSingleCustom rather than track and trackCustom, like so:

fbq("trackSingle, "[your-pixel-id]", "ViewContent", { content_type: "product", content_ids: ['892185001003'] });

But a problem remains with this paradigm: if even one developer on a site with multiple pixels doesn't use the new actions, his events will track to everyone's pixel IDs on the site. From what I've seen in the past few months, nearly every developer still uses the track action. I should say here that it's not the end of the world if other developers track their events to your pixel, but I like the idea of not junking up my data and possibly throwing off analytics and/or conversion measurement.

So, the problem remains: how do you track pixel events to only your pixel, and not let anyone else track their events to your pixel too?

The <noscript> method of tracking a pageview event to Facebook gave me a hint that you can do this, just not via the fbq object.

In an answer by Flavio Wuensche, he actually implemented this idea. I took it, cleaned it up, and modified it.

Code

(function (window, document) {
    if (window.myfbq) return;
    window.myfbq = (function () {
        if (arguments.length > 0) {
            var pixelId, trackType, contentObj;

            if (typeof arguments[0] == 'string') pixelId = arguments[0];
            if (typeof arguments[1] == 'string') trackType = arguments[1];
            if (typeof arguments[2] == 'object') contentObj = arguments[2];

            var params = [];
            if (typeof pixelId === 'string' && pixelId.replace(/\s+/gi, '') != '' &&
            typeof trackType === 'string' && trackType.replace(/\s+/gi, '')) {
                params.push('id=' + encodeURIComponent(pixelId));
                switch (trackType) {
                    case 'PageView':
                    case 'ViewContent':
                    case 'Search':
                    case 'AddToCart':
                    case 'InitiateCheckout':
                    case 'AddPaymentInfo':
                    case 'Lead':
                    case 'CompleteRegistration':
                    case 'Purchase':
                    case 'AddToWishlist':
                        params.push('ev=' + encodeURIComponent(trackType));
                        break;
                    default:
                        return;
                }

                params.push('dl=' + encodeURIComponent(document.location.href));
                if (document.referrer) params.push('rl=' + encodeURIComponent(document.referrer));
                params.push('if=false');
                params.push('ts=' + new Date().getTime());

                if (typeof contentObj == 'object') {
                    for (var u in contentObj) {
                        if (typeof contentObj[u] == 'object' && contentObj[u] instanceof Array) {
                            if (contentObj[u].length > 0) {
                                for (var y = 0; y < contentObj[u].length; y++) { contentObj[u][y] = (contentObj[u][y] + '').replace(/^\s+|\s+$/gi, '').replace(/\s+/gi, ' ').replace(/,/gi, '§'); }
                                params.push('cd[' + u + ']=' + encodeURIComponent(contentObj[u].join(',').replace(/^/gi, '[\'').replace(/$/gi, '\']').replace(/,/gi, '\',\'').replace(/§/gi, '\,')));
                            }
                        }
                        else if (typeof contentObj[u] == 'string')
                            params.push('cd[' + u + ']=' + encodeURIComponent(contentObj[u]));
                    }
                }

                params.push('v=' + encodeURIComponent('2.7.19'));

                var imgId = new Date().getTime();
                var img = document.createElement('img');
                img.id = 'fb_' + imgId, img.src = 'https://www.facebook.com/tr/?' + params.join('&'), img.width = 1, img.height = 1, img.style = 'display:none;';
                document.body.appendChild(img);
                window.setTimeout(function () { var t = document.getElementById('fb_' + imgId); t.parentElement.removeChild(t); }, 1000);
            }
        }
    });
})(window, document);

Usage

myfbq("[your-pixel-id]", "PageView");
myfbq("[your-pixel-id]", "ViewContent");
myfbq("[your-pixel-id]", "ViewContent", { content_type: "product", content_ids: ['892185001003'] });

Further Discussion

Note that this myfbq function has no association or ties to the fbq object. It simply dynamically inserts <img> tags on the site that make calls to Facebook to track events for individual pixels. So, you can track events to all pixels initialized on the site (or a single pixel using the new functionality) via the normal Facebook pixel code snippet, or to just your own pixel ID with the myfbq function, or you can do both!

If you want to do both, include the myfbq function on the site, then your Facebook pixel code snippet could look like this:

<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','//connect.facebook.net/en_US/fbevents.js');
    fbq('init', '12345678');
    fbq('init', '87654321');
    fbq('track', 'PageView'); //tracks a PageView event to all initialized pixels

    myfbq("87654321", "ViewContent", { content_type: "product", content_ids: ['892185001003'] }); //tracks a ViewContent event to only one pixel, with your own unique ProductId
</script>
<noscript>
    <img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=12345678&ev=PageView&noscript=1" />
    <img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=87654321&ev=PageView&noscript=1" />
</noscript>

Upvotes: 6

t-storm
t-storm

Reputation: 101

FWIW, Facebook has added trackSingle and trackSingleCustom events (as of November 2017) to allow selectively firing events on specific pixels when multiple pixels are initialized on a page.

Docs: https://developers.facebook.com/docs/facebook-pixel/events-advanced-use-cases/v2.12#multipixels.

Blog Post: https://developers.facebook.com/ads/blog/post/2017/11/28/event-tracking-with-multiple-pixels-tracksingle/

Upvotes: 8

Rangi Lin
Rangi Lin

Reputation: 9461

https://www.facebook.com/business/help/community/question/?id=10100525729830570

According to Facebook Help Team :

Although this should be fine we're unable to guarantee the accuracy of the results if multiple pixels are installed on the same webpage and have received reports of discrepancies from people who've tried this in the past.

Upvotes: 6

Flavio Wuensche
Flavio Wuensche

Reputation: 10376

Multiple Facebook Pixels Code

In order to be able to trigger distinct events to different Facebook pixels, without having it called to all previously initialized Facebook pixels, you can overwrite the fbq function (by copying and pasting the snippet below to your code base) and then call the tracking events as explained on the Usage section below.

<script type="text/javascript">
(function() {
  var fbq = (function() {
    function fbq()
    {
      if(arguments.length > 0) {
        var action, pixel_id, type_track, content_obj;

        if( typeof arguments[0] == "string") action = arguments[0];
        if( typeof arguments[1] == "string") pixel_id = arguments[1];
        if( typeof arguments[2] == "string") type_track = arguments[2];
        if( typeof arguments[3] == "object") content_obj = arguments[3];

        var params = [];
        if(typeof action == "string" && action.replace(/\s+/gi, "") != "" &&
        typeof pixel_id == "string" && pixel_id.replace(/\s+/gi, "") != "" &&
        typeof type_track == "string" && type_track.replace(/\s+/gi, "")) {

          params.push("id=" + encodeURIComponent(pixel_id));
          switch(type_track) {
            case "PageView":
            case "ViewContent":
            case "Search":
            case "AddToCart":
            case "InitiateCheckout":
            case "AddPaymentInfo":
            case "Lead":
            case "CompleteRegistration":
            case "Purchase":
            case "AddToWishlist":
            params.push("ev=" + encodeURIComponent(type_track));
            break;
            default:
            return;
          }

          params.push("dl=" + encodeURIComponent(document.location.href));
          params.push("rl=" + encodeURIComponent(document.referrer));
          params.push("if=false");
          params.push("ts=" + new Date().getTime());

          if(typeof content_obj == "object") {
            for(var u in content_obj) {
              if(typeof content_obj[u] == "object" && content_obj[u] instanceof Array) {
                if(content_obj[u].length > 0) {
                  for(var y=0; y<content_obj[u].length; y++) { content_obj[u][y] = (content_obj[u][y]+"").replace(/^\s+|\s+$/gi, "").replace(/\s+/gi," ").replace(/,/gi, "§"); }
                  params.push("cd[" + u + "]=" + encodeURIComponent(content_obj[u].join(",").replace(/^/gi, "[\"").replace(/$/gi, "\"]").replace(/,/gi, "\",\"").replace(/§/gi, "\,")));
                }
              }
              else if(typeof content_obj[u] == "string")
              params.push("cd[" + u + "]=" + encodeURIComponent(content_obj[u]));
            }
          }

          params.push("v=" + encodeURIComponent("2.5.0"));

          if(typeof window.jQuery == "function") {
            var iframe_id = new Date().getTime();
            jQuery("body").append("<img height='1' width='1' style='display:none;width:1px;height:1px;' id='fb_" + iframe_id + "' src='https://www.facebook.com/tr/?" + params.join("&") + "' />");
            setTimeout(function() { jQuery("#fb_" + iframe_id).remove(); }, 1000);
          }
        }
      }
    }

    return fbq;
  });

  window.fbq = new fbq();
})();
</script>

Usage

Now the fbq function takes 3 parameters. The first param will be just "track". The second one is new, that's where you can specify the Facebook pixel ID you want to use to track this specific event. Third, as usual, say the event name. And, lastly, you can pass other options such as purchase value, currency, content_ids, etc.

<script>
  fbq('track', '<FIRST_PIXEL_ID>', 'PageView');
  fbq('track', '<FIRST_PIXEL_ID>', 'Purchase', {value: 79.9, currency: 'BRL'});
  fbq('track', '<SECOND_PIXEL_ID>', 'Purchase', {value: 89.9, currency: 'BRL'});
</script>

Note that you can also use different purchase values for different pixels, and they will only be fired to that very specific pixel.

Demo

You can find the results in this product page, though I didn't use different data on the product page. But I use it to trigger Purchase events with different purchase values on the checkout. Also, if you don't have it yet, please download the Facebook Pixel Helper extension for Google Chrome. It'll help you debugging the Facebook Pixel.

Upvotes: 4

cilantro
cilantro

Reputation: 550

The Facebook Conversion Pixel code has been updated to enable advertisers to track multiple pixels within the same web page. Previously if you had multiple versions of the Conversion Tracking pixel on the same page caused collisions and led to data loss. The new code also makes it easier to track in-page actions such as clicks on a button.

See this.

Upvotes: 2

Related Questions