Facebook Pixel and respecting Do Not Track

Some clients (naming no names) choose to use Facebook Pixel tracking code on their sites. I understand the need to monitor performance and improve websites; all my clients are doing important work to improve the world we live in and some think that using Facebook's almost ubiquitous tracking code is a necessary evil.

But this must come second to respecting privacy.

Browsers' Do Not Track (DNT) mechanism gives users a configuration switch for telling websites that they don't want to be tracked. It's up to websites to respect (or not) that preference, and I think it's a great way to give users a say in their privacy, so I always recommend to clients that I implement protection from tracking technologies when users have set DNT.

Here's my doctored facebook tracking code (note that you need to replace 1231231321 with your Facebook pixel ID):

<!-- Facebook Pixel Code -->
// This next line is added by me 
if (!(navigator.doNotTrack == 1)) {
fbq('init', '123456789123456');
fbq('track', 'PageView');
// This next line is added by me
<!-- This next line is altered by me: We also protect noscript types from the pixel by proxying it to check for DNT -->
<noscript><img height="1" width="1" src="/facebook-noscript-pixel.php?nocache=1"/></noscript>
<!-- End Facebook Pixel Code -->

I've made two changes:

  1. I check the browser's DNT setting in Javascript and only include the tracking code if the user does not have that set. This protects the majority of users who browse with Javascript enabled.
  2. For noscript users who disable Javascript, Facebook would normally load a pixel image to track them. I guard against this by installing a small PHP script that checks for DNT

Protecting against the img pixel

This needs to be done server-side. Servers can observe DNT by checking for it in the HTTP headers. We could check for this header and simply not include any of the tracking code in the output if that header is present. However, this comes at the cost of needing to disable caching since every page request then needs individual processing.

My sites make the most of caching for simple requests to improve performance. This is done at several levels and I did not want to undo all the benefits, so I needed a lighter solution. So instead I made a small lightning fast PHP script that does not need to boot a CMS or connect to a database, which checks for the DNT header. If found it  returns a plain single pixel GIF image itself and no tracking occurs. If not found it issues an HTTP Location header redirecting the browser to fetch the original Facebook pixel.

This does add an extra HTTP request to the site, but it's much more performant than disabling caching.

Here's the script (note that you need to replace 1231231321 with your Facebook pixel ID):

// Call this with: /facebook-noscript-pixel.php?nocache=1
if (!($_SERVER['HTTP_DNT'] ?? false)) {
  // OK, they don't have DNT set, redirect to the facebook pixel.
  header("Location: https://www.facebook.com/tr?id=123123123123&ev=PageView&noscript=1");
else {
  // They have DNT set, issue a blank png.
  header('Content-Type: image/gif');
  echo "\x47\x49\x46\x38\x37\x61\x1\x0\x1\x0\x80\x0\x0\xfc\x6a\x6c\x0\x0\x0\x2c\x0\x0\x0\x0\x1\x0\x1\x0\x0\x2\x2\x44\x1\x0\x3b";


Add new comment