We are trying to use Facebook\'s Ad tracking pixels to track ads. we looked at Facebook\'s documentation and that led me no where.
I need to know how to trigger mult
According to FB's recommendation, it's very easy to track different events to different pixels:
fbq('trackSingle', 'FB_PIXEL_ID', 'Purchase', customData);
fbq('trackSingleCustom', 'FB_PIXEL_ID', 'CustomEvent', customData);
https://developers.facebook.com/docs/facebook-pixel/api-reference#tracking-events-for-individual-pixels
I was running into the same problem and I couldn't find the solution anywhere. I dug into the code and found a method you can used called "addPixelId". In my testing, you can use this right after the "init", which will add a second ID. Any events you track will now send to both IDs. For example:
fbq('init', 'xxxxxxxxxxxxx12');
fbq('addPixelId', 'xxxxxxxxxxxxx34');
fbq('addPixelId', 'xxxxxxxxxxxxx56');
fbq('track', 'PageView');
The only other thing to be aware of is any events you track will be tracked for all IDs that you have defined. It's been working fantastic for me, no issues whatsoever.
One other solution would be just to use the no-javascript approach if you want to track only certain events for certain pixel IDs
You can see some examples in their docs: https://developers.facebook.com/docs/facebook-pixel/api-reference
<img height="1" width="1" style="display:none"
src="https://www.facebook.com/tr?id=FB_PIXEL_ID&ev=MyCustomEvent&cd[custom_param]=custom_value"
/>
<img height="1" width="1" style="display:none"
src="https://www.facebook.com/tr?id=FB_PIXEL_ID&ev=PageView&noscript=1"
/>
You just need to get the parameter formatting right.
The issue is that the Facebook Pixel code/initialization can take a little bit of time to load not to mention a user's connection and device will also affect the init time.
You DO NOT want to paste the code three times.
First call the core FB JS Pixel code that references the fbevents.js
library
!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');
Then create your array of pixel ids
// Array of FB PixelIDs
var pixel_ids = ['xxx111','xxx222'];
Iterate over the array and call each pixel initialization with a small delay. I'd tweak it to meet your needs. You'll need to use a closure function to ensure the proper value of your array is assigned.
// Iterate over the ids and ensure each one is initialized
for (var i = 1; i <= pixel_ids.length; i++){
// Add delay here to allow each pixel to instantiate
setTimeout(function(x) { return function() {fbq('init',x.toString());};
}(pixel_ids[i-1]), 33*i);
}
Now it's time to call your actual tracking events also with a delay to ensure they are fired after pixel initialization.
setTimeout(function() { fbq('track', "PageView");}, (33*pixel_ids.length)+33);
setTimeout(function() { fbq('track', 'Purchase', {value: '1.00', currency: 'USD'});},(33*pixel_ids.length)+66);
For good measure put a HTML no script call to PageView
for each pixel
<noscript><img height="1" width="1" style="display:none"
src="https://www.facebook.com/tr?id=xxx111&ev=PageView&noscript=1"/>
</noscript>
<noscript><img height="1" width="1" style="display:none"
src="https://www.facebook.com/tr?id=xxx2222&ev=PageView&noscript=1"/>
</noscript>
The number of events fired should equal the number of pixels you have times the number of events (i.e. each event registered for each pixel) ... there should not be errors if you implement right.
Simply put in one JS file this code: //Facebook Multi-Pixel
(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();
})();
And than, usage example:
fbq('track', "<PIXEL_ID>", "PageView");
fbq('track", "<PIXEL_ID>", "ViewContent", {
content_name: "name test",
content_category: "category test",
content_ids: ["test"],
content_type: "product",
value: 7.99,
currency: "GBP"
});
and so on.
@ClosDesign, you're on the right track! As you suspected, you can call fbq('init', '[your-pixel-id]')
multiple times, which adds each pixel ID to the list of IDs that all events will be tracked to. I wrote a blog post about this issue of using multiple Facebook pixels on one site, so read there for more details.
Using your example code, you first want to include Facebook's JavaScript pixel code. This will load the JavaScript from Facebook that is needed to send pixel events with their fbq
object:
!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');
Then, it's time to init
all pixel IDs:
fbq('init', 'xxxxxxxxxxxxx12');
fbq('init', 'xxxxxxxxxxxxx34');
fbq('init', 'xxxxxxxxxxxxx56');
Once you have initialized all the pixel IDs on your site with fbq('init')
, use the Facebook Pixel Helper to confirm all pixels have been loaded. You can also manually confirm they have been loaded by running the following code in the JavaScript console:
fbq.getState().pixels
After that, any calls you make to track
an event will be tracked to all pixel IDs you initialized above. So if you call:
fbq('track', "PageView");
A PageView
event will be sent to Facebook for all three pixels. Your Purchase
event works the same way.
When it comes to the <noscript>
tags Facebook includes, you would need to include an <img>
tag for each pixel ID you want to call on your site:
<noscript>
<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=xxxxxxxxxxxxx12&ev=PageView&noscript=1" />
<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=xxxxxxxxxxxxx34&ev=PageView&noscript=1" />
<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=xxxxxxxxxxxxx56&ev=PageView&noscript=1" />
</noscript>
Note that if the user has JavaScript turned off, those <img>
tags only send a request to Facebook to track a PageView
event. The Purchase
event will not be tracked unless you create another <img>
tag for each pixel ID and specify data for tracking the Purchase
event also.
A natural next question is, "Can I track an event to only one of many pixels initialized on my site?" Not using Facebook's fbq
object, no.
There is a workaround to this, however. Using the <img>
tag method above, you can send events to Facebook and only track the event to one pixel ID. This method bypasses the fbq
object entirely and dynamically builds an <img>
tag with the event information you specify.
(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);
myfbq("[your-pixel-id]", "PageView");
myfbq("[your-pixel-id]", "ViewContent");
myfbq("[your-pixel-id]", "ViewContent", { content_type: "product", content_ids: ['892185001003'] });