Simon_Weaver
Simon_Weaver

Reputation: 146208

Track campaigns with Google Analytics without query string parameters?

Is there a supported way in Google Analytics to track a campaign without having to use query string parameters.

In Analytics you can tag a link to your site with query string parameters such as utm_campaign and utm_medium which carry information about the campaign so that they can be tracked.

Google actually has an online tool to help in the creation of such links.

For instance if StackOverflow was advertising on Experts Exchange they may have a link like this :

http://www.stackoverflow.com/?utm_source=expertexchange&utm_medium=banner&utm_campaign=a-better-expert-exchange

For many reasons I don't want these clumsy looking parameters appearing in my URLS :

I looked a while ago to try to find a way wherein you could set these parameters. Google has a page which at first glance looks like the solution, but actually isn't. That page describes how you can change the names of the query string parameters to something else - for instance to use src instead of utm_source you would run :

 pageTracker._setCampSourceKey("src");     

I really cannot seem to figure out why they don't make it easy to actually explicitly set the value of the utm_source key - and not just set up an alternative parameter name for it.

I remember a while back finding someone who had a kind of nasty hack, but I cant even seem to find that now. I seem to recall though that whoever it was took a copy of the analytics code and essentially branched it off and hacked at it. This is not a good solution for me!

is there an officially supported way of doing this at all, without some kind of nasty redirects.

In a nutshell I want to do something like this (ASP.NET MVC site). Give a partnet a link to my site with a URL like this :

 http://www.example.com/?cid=2dae88a8-66b1-475d-8a35-2978bd1a158c

In the controller for my MVC page I would find out what campaign this GUID related to, and set the model state. Note: this gives me the advantage that i can change the campaign parameters without having to reissue the URL.

In the page itself I would then do this:

var campaignMedium = <%= ViewData.Model.CampaignMedium %>;
var campaignSource = <%= ViewData.Model.CampaignSource %>;
var campaignName = <%= ViewData.Model.CampaignName %>;

pageTracker._setCampaignData({
    utm_source: campaignSource,
    utm_medium: campaignMedium,
    utm_campaignName: campaignName
});
pageTracker._trackPageview();

IMPORTANT: This _setCampaignData method DOES NOT ACTUALLY EXIST. This is just 'pseudo code' for what I'd ideally like to be able to do.

Has anyone successfully managed to do anything like this?

Upvotes: 45

Views: 23275

Answers (10)

theblang
theblang

Reputation: 10425

Continuing the update train for Google Analytics 4, see this article.

  • We're using Google Tag Manager to install GA4, so we used the instructions to override fields in the GA4 Configuration tag.

  • There's also instructions for overriding the gtag.js library in code:

      gtag('set', {
          'campaign_id': 'google_1234',
          'campaign_name': 'Summer_fun',
          'campaign_source': 'google',
          'campaign_medium': 'cpc',
          'campaign_term': 'summer+travel',
          'campaign_content': 'logolink',
      });
    

Upvotes: 1

brass monkey
brass monkey

Reputation: 6781

The solution using push(['_set', 'campaignParams',... seems only to work for the legacy library ga.js.

Using analytics.js you need to specify the campaign param separately. E.g.

ga('set', 'campaignName', 'TheCampaignName...');
ga('set', 'campaignSource', 'someCampaignSource');
ga('set', 'campaignMedium', 'email');

https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#campaignName

Upvotes: 10

Yahel
Yahel

Reputation: 37315

_set campaignParams

Your theoretical "_setCampaignData" finally exists, in the form of ["_set","campaignParams",...]

If you have a way to programmatically inject the values you'd like to set (for example, set by a cookie on a redirect, or on the server side and printed onto the page), you can use the _set API to hard-code the campaign params that you'd like to set.

The format for that is just:

_gaq.push(['_set', 'campaignParams', 
'utm_campaign=CAMPAIGN&utm_source=SOURCE&utm_medium=MEDIUM']);

So, using your original example:

 var campaignMedium = <%= ViewData.Model.CampaignMedium %>;
 var campaignSource = <%= ViewData.Model.CampaignSource %>;
 var campaignName = <%= ViewData.Model.CampaignName %>;
 _gaq.push(['_set', 'campaignParams', 
'utm_campaign=' + campaignName +  '&utm_source=' + campaignSource +'&utm_medium=' + campaignMedium]);

Update 2017

This answer details how to accomplish this with the newer Google Analytics library, analytics.js/Universal Analytics.

Upvotes: 32

Brady Moritz
Brady Moritz

Reputation: 8895

The new(er) universal analytics allows you to specify these params - see the documentation here https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference

Look for the "Campaign Source" section for an example of setting what would be the utm_source param.

Upvotes: 2

Israel  Kloss
Israel Kloss

Reputation: 51

Below is an updated way to do this using the Google Analytics Universal method of Event tracking rather than GA Standard Event tracking.

The entire UTM string can be extracted from the queryString (when there) or pulled from the Google cookie (__utmz) and then passed into Google Analytics using the below code.

ga('send', 'event', 'queryString', 'getQueryString', googleString ); 

Then, upon execution of whatever trigger you want to create (I use a function named "widgetTracker"), you can execute the GA event tracker.

Here's the entire code:

/* JavaScript Document */
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
  ga('create', 'UA-xxxxxxx-xx', 'xx.xxx');
  ga('send', 'pageview');

 var googleString;  
 var stringArray = [];  
 var queryStringObject = makeQueryStringObject();   
 var QUOT = "'";    
 var EQ = '=';  
 var AMP = '&';         

 for  ( var v in queryStringObject ) {  
    var str =  v + EQ + queryStringObject[v] ;  
    stringArray.push(str);   
    googleString = stringArray.join(AMP);
} 

         function makeQueryStringObject()   {       
            var obj = [];       
            var pageURL = window.location.href;         
            var URLArray = pageURL.split('?');      
            if( URLArray[1] )       {           
                var argsArray = URLArray[1].split('&');             
                var l = argsArray.length;           
                for( i=0; i<l; i++ )            {               
                    var individualArg = argsArray[i].split('=');                
                    if(individualArg[1] && individualArg[1].indexOf('#') > -1)              {               
                        var dropHashArray = individualArg[1].split('#');                    
                        individualArg[1] = dropHashArray[0];                
                    }               
                    obj[ individualArg[0] ] = individualArg[1];     
                    console.log("value of queryStringObject: " + individualArg[0] + " :: " + obj[   individualArg[0] ]);

                }       
            } else { /* from http://stackoverflow.com/a/14984832/1013405 */         
                ga1 = parseGACookie();  
                if(ga1['utmcsr']) {             
                    var utm_source = ga1['utmcsr'];                     
                }           
                    if(ga1['utmccn']) {             
                        var utm_campaign = ga1['utmccn'];                   
                    }           if(ga1['utmcmd']) {             
                        var utm_medium = ga1['utmcmd'];                 
                        }           
                        if(ga1['utmctr']) {             
                            var utm_term = ga1['utmctr'];                           
                        }           
                        if(ga1['utmcct']) {             
                            var utm_content = ga1['utmcct'];                
                        }       
                    }   
                        var googleString2 = "utm_campaign=" + utm_campaign + '&' + "utm_medium=" + utm_medium + '&' + "utm_term=" + utm_term + '&' + "utm_content=" + utm_content;  
                    return obj;     
                } 

                function parseGACookie()  {     
                var values = {};     
                var cookie = readCookie("__utmz");     
                if (cookie) {         
                    var z = cookie.split('.');         
                    if (z.length >= 4) {             
                        var y = z[4].split('|');            
                         for (i=0; i<y.length; i++) {                 
                            var pair = y[i].split("=");                 
                            values[pair[0]] = pair[1];             
                         }         
                        }     
                    }     
                    return values; 
                }  


                function readCookie(name) {     
                    var nameEQ = name + "=";     
                    var ca = document.cookie.split(';');     
                    for(var i=0;i < ca.length;i++) {        
                     var c = ca[i];        
                      while (c.charAt(0)==' ') c = c.substring(1,c.length);         
                      if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);     
                    }     
                    return null; 
                }  
                function widgetTracker() {  
                /* event tracking order of elements: send (required), event (required), Category, Action, Label, Value */ 
                    if (googleString) { 
                    ga('send', 'event', 'queryString', 'getQueryString', googleString ); 
                    } else { 
                     ga('send', 'event', 'queryString2', 'getQueryString2', googleString2 ); 
                     }
                }  

Upvotes: 7

detentionhall
detentionhall

Reputation:

I posted this to the Google help forum.

Google Please Read!!! Great enhancement opportunity!!! This is causing a lot of users not to be able to use the Advertising parameters. Allow the Advertising parameters to be read from the URL used on trackPageview(url).

In any case, without this capability, I had to use a work-around. Rather than appending the parameters to the URL. I temporarily appended them to the URL as a bookmark. Then I removed them after the trackPageview call. By adding them as a bookmark, the page is no reloaded. See the following example.

var pageTracker = _gat._getTracker(param);
var orighash = document.location.hash;
if (orighash == "") {
    orighash = "none";  // this is done to prevent page scrolling
}
document.location.hash = 'utm_source='+source+'&utm_campaign='+campaign+'&utm_medium='+medium+'&utm_content='+content;
pageTracker._setAllowAnchor(true);
pageTracker._trackPageview();
document.location.hash = orighash

Upvotes: 7

Maciej Łebkowski
Maciej Łebkowski

Reputation: 3942

Török Gábor gave me an idea.

// ...
var campaignMedium = <%= ViewData.Model.CampaignMedium %>;
var campaignSource = <%= ViewData.Model.CampaignSource %>;
var campaignName = <%= ViewData.Model.CampaignName %>;

// save the old hash
var oldHash = document.location.hash;

// add campaign data to the hash
document.location.hash = 'utm_source=' + escape(campaignSource) + ...;
pageTracker._setAllowAnchor(true);
pageTracker._trackPageview();
// restore the old hash:
document.location.hash = oldHash;

This way, you could create the campaign data in the backend, and then, pass it to the hash dynamically, and then restore it without user even noticing it. I.e. the campaign tracking is 100% independent of the real URL.

Upvotes: 11

Maciej Łebkowski
Maciej Łebkowski

Reputation: 3942

Well, I didn’t test it, but try to add those params to the .trackPageview() method, i.e.:

pageTracker._trackPageview("?utm_source=...")

Anyways, You have to pass those parameters some how. And this means, you’ll allways have long URL-s with some kind of campaign crap in them. It won’t prevent bookmarking the wrong URL-s, search engines indexing them, etc.

If you want to maintain control of those parameters, setup separate URL-s for partners, that redirects to the tagged target URL:

http://example.com/campaigns/1 -> http://example.com/?utm_source=...

Upvotes: 3

viam0Zah
viam0Zah

Reputation: 26322

There is a function _setAllowAnchor in the Trackin API that allows you to specify the tags in the anchor text instead of as query parameters.

pageTracker._setAllowAnchor(true);

So you can use http://www.stackoverflow.com/#utm_source=expertexchange and GA will understand it. This way you can avoid the SEO problem.

For the Twitter problem, I suggest you the method described in post Tracking Twitter and Shorten URLs in Google Analytics.

Upvotes: 7

Jay Stevens
Jay Stevens

Reputation: 5913

You can use the Google Analytics API to customize the call to _trackPageview in your example.

pageTracker._trackPageview("/inbound/" + campaignSource + "/" + campaignMedium );

All of the inbound links will then show up in Google Analytics under the /inbound/ "pseudo directory" with a separate "directory" for Campaign Source and Campaign Medium.

Upvotes: 2

Related Questions