Do Not Track

Publisher: TJ Fogarty

Modified: 2018-04-15

When I first began writ­ing posts for my own web­site, I was keen to get an insight into how peo­ple were find­ing my blog, what pages were most pop­u­lar, and gen­er­al­ly nerd­ing out with the real-time dash­board in Google Ana­lyt­ics to see vis­i­tors from dif­fer­ent parts of the world.

Those things def­i­nite­ly still inter­est me, but over time I haven’t real­ly used any of the infor­ma­tion I get in a mean­ing­ful way. I imag­ine for oth­er sites it’s more use­ful, espe­cial­ly if you need to run some ads, or it’s part of your income or a ser­vice you offer and you want to see if users are hit­ting any issues. That’s super impor­tant stuff, and I don’t see a prob­lem with it. The way it looks to be going now, how­ev­er, is that it’s becom­ing more of an opt-in expe­ri­ence rather than one of opt-out.

This is a pret­ty small site, and since it’s devel­op­er-focused I’m imag­in­ing a good num­ber of vis­i­tors have some sort of ad block­er enabled. I have one myself, and sure I’ll dis­able it for sites I trust, but for the most part it’s left on by default. I’ve been recent­ly toy­ing with the idea of remov­ing track­ing alto­geth­er for my site in it’s cur­rent state, but first I want­ed to see if there was any mid­dle-ground to explore. Enter navigator.doNotTrack.

I found some docs on MDN describ­ing how it can be used, and there’s a dif­fer­ence in behav­iour across browsers. It seems by default in Chrome and Safari, the val­ue is null, where­as in Fire­fox it’s "unspecified". If you call navigator.doNotTrack and it returns a string val­ue of "1", then it means the request prefers no track­ing. I’m going to be lean­ing more towards an opt-in approach, how­ev­er if it returns null then I’ll enable Google Ana­lyt­ics. You can find this option in your brows­er set­tings. In Safari it’s under Pri­va­cy, and in Chrome and Fire­fox you can search your set­tings for do not track”.

Here’s how I’m check­ing at the moment:

function hasDoNotTrackEnabled() {
  let doNotTrack = navigator.doNotTrack

  // some browsers have this in the window object
  if ('doNotTrack' in window) {
    doNotTrack = window.doNotTrack

  // if it isn't specified, let's not assume
  if (doNotTrack === 'unspecified') return true

  return doNotTrack === '1'

It would be nice if it always had a val­ue like Fire­fox does, but I’m gonna roll with this for now. Chances are it’ll com­plete­ly dis­able track­ing for Fire­fox users, and enable it for Chrome and Safari users if they don’t say oth­er­wise which kin­da cir­cum­vents the opt-in approach. Short of remov­ing ana­lyt­ics alto­geth­er I think this is an OK approach for now.

I’m using the ga-lite pack­age to bun­dle every­thing so I have clean­er con­trol over how track­ing works.

import galite from 'ga-lite'
import { env, hasDoNotTrackEnabled } from './utils'

export const Tracking = {
  gaTrackingId: 'UA-XXXXXXX-X',
  shouldTrack: env() === 'production' && !hasDoNotTrackEnabled(),

  setup() {
    if (!this.shouldTrack) return

    galite('create', this.gaTrackingId, 'auto')

  sendPageView() {
    if (!this.shouldTrack) return

    galite('send', 'pageview')

The env() call is a util­i­ty func­tion I can use so I don’t run it when devel­op­ing locally.

So now when I call Tracking.setup() and Tracking.sendPageView(), it’ll do it based on the result of the hasDoNotTrackEnabled function.

I’ll keep this going for a while, and prob­a­bly end up remov­ing track­ing alto­geth­er at some stage. Just to re-iter­ate though, I have no prob­lem with sites using some form of track­ing. This is more of a per­son­al deci­sion. It’d be nice if it got to a stage where some­thing like Car­bon Ads would be need­ed to help pay for host­ing, and I’d recon­sid­er then if I need­ed to get a rough esti­ma­tion of traf­fic. At the end of the day it’s a tool to be used, and we shouldn’t be shamed out of tak­ing advan­tage of it (pro­vid­ed it’s not for nefar­i­ous rea­sons, of course).