Understand how many www.mozilla.org visitors have DNT enabled

RESOLVED FIXED

Status

www.mozilla.org
Analytics
RESOLVED FIXED
3 years ago
3 years ago

People

(Reporter: cmore, Assigned: kohei)

Tracking

Production

Firefox Tracking Flags

(Not tracked)

Details

(Whiteboard: [kb=1560776] )

Attachments

(1 attachment)

(Reporter)

Description

3 years ago
We would like to understand what impact of making www.mozilla.org respond to a DNT signal. After we understand the magnitude of users and what percentage of site visitors have DNT enabled, we'll determine next steps on what actions would take if the signal is true. The first step is just learning.

Let's set a GA custom event when DNT is enabled, run it for a few weeks, and then turn it back off. This should get us a good baseline of data.

The following should work cross-platform.

if ( navigator.doNotTrack == "yes" || navigator.doNotTrack == "1" || navigator.msDoNotTrack == "1" {
{
 _gaq.push(['_trackEvent', 'DNT Signal', 'Status', 'True']);
}

We can add the check in the main GA include on bedrock:

https://github.com/mozilla/bedrock/blob/master/bedrock/base/templates/includes/google-analytics.html
(Reporter)

Comment 1

3 years ago
:garethc: can you verify if this is the event you want to sent on mozilla.org?
Flags: needinfo?(garethcull.bugs)
(Assignee)

Comment 2

3 years ago
As I documented here, Firefox 31 and below were returning a wrong value. We could probably exclude these older versions of Firefox.

https://developer.mozilla.org/en-US/Firefox/Releases/32/Site_Compatibility#DOM
(Reporter)

Comment 3

3 years ago
opps, condition was mixed up.

if ( navigator.doNotTrack == "yes" || navigator.doNotTrack == "1" || navigator.msDoNotTrack == "1")
{
 _gaq.push(['_trackEvent', 'DNT Signal', 'Status', 'True']);
}
(Reporter)

Comment 4

3 years ago
(In reply to Kohei Yoshino [:kohei] from comment #2)
> As I documented here, Firefox 31 and below were returning a wrong value. We
> could probably exclude these older versions of Firefox.
> 
> https://developer.mozilla.org/en-US/Firefox/Releases/32/
> Site_Compatibility#DOM

Hmm, that's not good.

Ok, what are your thoughts on this pseudo code:

if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1){
   if ( FirefoxVersion > 32.0 && navigator.doNotTrack == "1" ){
     Status = "1"; // enabled
   } else {
     Status = "Unknown"; // Can't say for sure if it is 1,0, or unspecified due to Fx bug 887703
   }
} else if (navigator.doNotTrack == "1" || navigator.msDoNotTrack == "1") {
     Status = "1"; // enabled
   } else {
     Status = "0"; // disabled or unspecified
}

 _gaq.push(['_trackEvent', 'DNT Signal', 'Status', Status]);
A couple questions:

1) How is this event being triggered? On every page? It may be better to use a custom variable and set this at the session level to go along with the _trackPageview. We would save requests to GA using a custom variable as the CV doesn't add any incremental hits when sent along via a pageview.

2) Are we considering implementing DNT to work with Google Analytics? I thought DNT was related to 3rd party ads and that we already point users to opt-out of any GA tracking via an addon?
Flags: needinfo?(garethcull.bugs)
(Reporter)

Comment 6

3 years ago
(In reply to Gareth Cull [:garethc] from comment #5)
> A couple questions:
> 
> 1) How is this event being triggered? On every page? It may be better to use
> a custom variable and set this at the session level to go along with the
> _trackPageview. We would save requests to GA using a custom variable as the
> CV doesn't add any incremental hits when sent along via a pageview.
> 
> 2) Are we considering implementing DNT to work with Google Analytics? I
> thought DNT was related to 3rd party ads and that we already point users to
> opt-out of any GA tracking via an addon?

+1 to custom variable. What would you recommend?

This is just to understand how many people have DNT set and if we would want to do anything with it. I think it is going to be a very small amount of people and thus probably not worth doing anything with. This is just a test to understand and no specific next steps. 

Hmmm, I wonder if we could use optimizely to detect the status and set a GA custom variable? Think that would work? Actually, I don't think it would work because the GA code is after optimizely in the head.
(Reporter)

Comment 7

3 years ago
Should we add this DNT check to Tabzilla so that we can check the DNT coverage across multiple websites instead of assuming the percentages are the same on each site? For example, DNT of visitors on developer.mozilla.org may be different to mozilla.org.
(Reporter)

Comment 8

3 years ago
kohei: thoughts on the logic in comment 4?
Flags: needinfo?(kohei.yoshino)
Hey Chris,

If we could pass the custom variable along with the _trackPageview call within the main snippet, that would be ideal. Something like this would work:

<script>
var _gaq = _gaq || [];
var pluginUrl = '//www.google-analytics.com/plugins/ga/inpage_linkid.js';
_gaq.push(['_require', 'inpage_linkid', pluginUrl]);
_gaq.push(['_setAccount', 'UA-36116321-1']);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_setAllowAnchor', true]);
_gaq.push(['_gat._anonymizeIp']);
_gaq.push(['_setCustomVar',13,'DNT',status,3]); // where status is 'enabled' or 'disabled'
_gaq.push(['_trackPageview']);

(function() {
    var ga = document.createElement('script');
    ga.type = 'text/javascript';
    ga.async = true;

    var prefix = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www');
    ga.src = prefix + '.google-analytics.com/ga.js';

    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(ga, s);
})();
</script>
(Assignee)

Comment 10

3 years ago
The detection code may look like this:

> var dnt = navigator.doNotTrack || navigator.msDoNotTrack;
> var status;
> 
> if (navigator.userAgent.match(/Firefox\/(\d+)/) && Number(RegExp.$1) < 32) {
>   // Can't say for sure if it is 1 or 0, due to Fx bug 887703
>   status = (dnt === 'yes') ? 'Unknown' : 'Unspecified';
> } else {
>   status = { '0': 'Disabled', '1': 'Enabled' }[dnt] || 'Unspecified';
> }
Flags: needinfo?(kohei.yoshino)
(Reporter)

Comment 11

3 years ago
:kohei: something like this?

<script>

// Check status of DNT signal
var dnt = navigator.doNotTrack || navigator.msDoNotTrack;
var status;
 
if (navigator.userAgent.match(/Firefox\/(\d+)/) && Number(RegExp.$1) < 32) {
   // Can't say for sure if it is 1 or 0, due to Fx bug 887703
   status = (dnt === 'yes') ? 'Unknown' : 'Unspecified';
 } else {
   status = { '0': 'Disabled', '1': 'Enabled' }[dnt] || 'Unspecified';
 }

var _gaq = _gaq || [];
var pluginUrl = '//www.google-analytics.com/plugins/ga/inpage_linkid.js';
_gaq.push(['_require', 'inpage_linkid', pluginUrl]);
_gaq.push(['_setAccount', '{{ settings.GA_ACCOUNT_CODE }}']);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_setAllowAnchor', true]);
_gaq.push(['_gat._anonymizeIp']);
_gaq.push(['_setCustomVar',13,'DNT',status,3]);
_gaq.push(['_trackPageview']);
{% if settings.GA_ACCOUNT_CODE %}
{% set GA_FILE = 'u/ga_debug.js' if settings.TEMPLATE_DEBUG else 'ga.js' %}
(function() {
var ga = document.createElement('script');
ga.type = 'text/javascript';
ga.async = true;
var prefix = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www');
ga.src = prefix + '.google-analytics.com/{{ GA_FILE }}';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ga, s);
})();
{% endif %}
</script>
Flags: needinfo?(kohei.yoshino)
(Assignee)

Comment 12

3 years ago
If the code goes into Tabzilla, it will be multiple domain tracking so things might be a bit complicated... I assume the code in Comment 11 would log every page view on Tabzilla-enabled Mozilla sites on the single www.mozilla.org GA profile (settings.GA_ACCOUNT_CODE = UA-36116321-1). Two possible solutions coming to my mind:

1. Create another multiple domain GA profile and use another tracker, instead of using the www.mozilla.org profile, so that the current profile won't be messy. It should work as per the GA support doc, but I cannot say there is no side effects.

https://support.google.com/analytics/answer/1032400
https://developers.google.com/analytics/devguides/collection/gajs/gaTrackingSite
http://www.blastam.com/blog/index.php/2013/04/using-multiple-trackers-in-google-analytics

2. Add the detection code and custom variable to each site, instead of using Tabzilla. Patches should be sent to Bedrock, MDN, SUMO, etc. so it needs additional work but should be safe.

Thoughts?

-----

One more thing... DNT is enabled by default on IE10 and later, so even if navigator.doNotTrack == 1, it's not clear whether it's the user's preference or the default setting. Should we treat such a case as "Unknown" like the older versions of Firefox?
Flags: needinfo?(kohei.yoshino)
One thing we would have to be aware of by adding an additional GA profile to moz.org is it would double our requests to Google. We've been sending a lot more requests to google recently with the increases in repeat traffic to whatsnew. Chris, how long do you want to run this for?
(Reporter)

Comment 14

3 years ago
(In reply to Gareth Cull [:garethc] from comment #13)
> One thing we would have to be aware of by adding an additional GA profile to
> moz.org is it would double our requests to Google. We've been sending a lot
> more requests to google recently with the increases in repeat traffic to
> whatsnew. Chris, how long do you want to run this for?

Given that mozilla.org has the most traffic than any other mozilla website, we should get a good sample of visitors. Let's just do this on mozilla.org to start and we'll see what the data tells us.
(Reporter)

Comment 15

3 years ago
> One more thing... DNT is enabled by default on IE10 and later, so even if
> navigator.doNotTrack == 1, it's not clear whether it's the user's preference
> or the default setting. Should we treat such a case as "Unknown" like the
> older versions of Firefox?

I would treat the IE default status as 1 for now. If and when we do something with DNT, we can decide to do something with IE vs non-IE users differently. We also via GA can look at the DNT status by browser and version later via segmentation.

Let's just do a PR to bedrock's google-analytics template that includes the DNT check and sets the custom variable. After we gather data for a few weeks, we can turn it back off and analyze the data. We just need to be aware of what data we could be losing and the impact to reports that it critical to discovering problems and improving UX.
(Assignee)

Comment 16

3 years ago
Created attachment 8513773 [details] [review]
pull request

Okay, here's a PR for Bedrock.
Assignee: nobody → kohei.yoshino
Status: NEW → ASSIGNED
(Assignee)

Updated

3 years ago
OS: Mac OS X → All
Hardware: x86 → All
Whiteboard: [kb=1560776]

Comment 17

3 years ago
:cmore - Would you be willing to write a short-ish explanation as to why we're collecting data on DNT users? During our PR triage yesterday, we felt that someone viewing the (uncompressed) JS could possibly interpret dubious intent. We'd like to add a comment in the JS to preemptively alleviate any potential concerns.

Updated

3 years ago
Flags: needinfo?(chrismore.bugzilla)

Comment 18

3 years ago
Just saw the comment on the PR. Thanks cmore!
Flags: needinfo?(chrismore.bugzilla)
(Reporter)

Comment 19

3 years ago
(In reply to Jon Petto [:jpetto] from comment #18)
> Just saw the comment on the PR. Thanks cmore!

Ok, cool. Thanks!
Have pushed Kohei's PR to demo2 for testing: https://www-demo2.allizom.org/

Gareth, can you please take a look to see if the data looks as expected cross-browser?

Thanks
Flags: needinfo?(garethcull.bugs)
(Reporter)

Comment 21

3 years ago
Code looks to be on demo2. testing now.
We discussed this in our weekly PR triage, and one thing we'd like to query is whether we really need to run this on every page on mozilla.org? It is going to send a *lot* of data to GA given the number of pages and amount of traffic the site gets.

Could we consider just running this on a reasonably high traffic page (e.g. the home page), and then using that sampled data instead to get an understanding on the figures?
(Reporter)

Comment 23

3 years ago
We've tested this on demo2 and we are able see the DNT status (enabled, disabled, unspecified) in GA. Let's run this for 3 weeks in production and then we can disable it completely. This will help gauge the impact to analytics if we were to ever to something with DNT.

Alex: The DNT flag doesn't send an additional request. It is part of the single pageview request that happens on every page. No additional requests, just a bit flipped in a request that is loaded onLoad.
Flags: needinfo?(garethcull.bugs)
(Reporter)

Comment 24

3 years ago
Let's get this on prod and not forget to turn it back off in December.

Comment 25

3 years ago
Commits pushed to master at https://github.com/mozilla/bedrock

https://github.com/mozilla/bedrock/commit/996f9e0df2e7a631c018748214f9367bfc10a9e5
Fix Bug 1087011 - Understand how many www.mozilla.org visitors have DNT enabled

https://github.com/mozilla/bedrock/commit/e83bf57866a99c357b3cd999d8d4b667ef3c1722
Merge pull request #2427 from kyoshino/bug-1087011-ga-dnt

Fix Bug 1087011 - Understand how many www.mozilla.org visitors have DNT enabled

Updated

3 years ago
Status: ASSIGNED → RESOLVED
Last Resolved: 3 years ago
Resolution: --- → FIXED
Filed Bug 1100841 for removal of this code on Monday 1 December

Updated

3 years ago
See Also: → bug 1136169
You need to log in before you can comment on or make changes to this bug.