Datalicious Blog - Data Driven Marketing
Filed under

tips

 

Testing Javascript code live in production without affecting live traffic

Save yourself some time, reduce your frustration, remove code deployment risk and improve your insight by using our technique to quickly test and deploy new web analytics code on your site without the need for staged testing.

Fear driven motivation ...

Quite frequently we needed to test site updates on a staging server for fear of breaking the production site, upsetting customers and losing revenue. This seems like a really good idea, except that when the files are pushed live things don't always happen quite as expected. Staging sites are never the same as production, we've seen perfect copies have issues with cookies due to the different domain, poor version control, different asset location and other network issues like load balancing amongst a range of other problems, the bottom line is they are never the same, period. 

In addition to the testing issues, we also need to deal with the fact that assets like Javascript are cached by some browsers. Code roll outs are not immediate, but dribble out over a period of up to a month as browsers invalidate their cache. This is a scary proposition for people relying on the analytics data, especially when frequent updates are required. 

Efficiency driven motivation ...

In addition to this, for many of our clients (e.g. banks) we have rare deployment windows as far as 6 months in the future (yes this is not an exaggeration) and aren't allowed to test code outside their building. We have other clients where we need to send them code and wait for a testing response when they can allocate the resources. The feedback loop becomes very slow and sometimes very minor code issues can cause significant deployment delays. The loss in revenue and general inability to find answers to key business questions in a timely manner cannot be underestimated.

Our background is in analytics and strategy, so we're usually dealing with Javascript files for tracking purposes, but the same issues occur with all asset based code updates. We want a simple means to test and deploy new code without making any on page changes or requiring testing in a staging environment. Maybe i'm lazy, but i don't want to test the same code twice! This initially sounds a bit ambitious, but it's actually pretty simple.

The solution ...

We use a single controlling file to include all other Javascript assets. The single file has the ability to switch between different Javascript file versions based on the existence of a cookie (created from a URL parameter when testing is required). This single file is also utilised to control the file version of the asset files without making any on page changes.

Advantages

  1. No on-page changes are required for Javascript updates EVER
  2. All updated files roll out instantly to everyone, there is no caching lag. Roll backs are just as easy.
  3. Testing on the live site can be performed without ever affecting a single other user. Staging sites are not required.
  4. Testing can be performed remotely (wherever the production site is accessible).
  5. Risk of web site down time or customer irritation is greatly reduced.
  6. Time to go live is significantly reduced.
  7. Development costs are significantly reduced.
  8. Javascript file names can include a version number, this greatly reduces confusion around version control.

Implementation

If you know Javascript and you're looking for an example, check out below. If you need more explanation, then drop us a line.

A. CONFIG
- Production server base location (e.g. www.client-site.com/js/)
- Test Server A base loca tion (e.g. www.your-live-test-site.com/client-folder/js/)
- Test Server B base location (e.g. www.client-site.com/js/live-test/). Maybe they want to test too!
- File version (or name, e.g. scode-v1.js)

B. DEFINE INCLUDE FUNCTION and OTHER BASE FUNCTIONS
These functions include setting and retrieving cookies, reading URL parameters into variables and including other javascript files.

function gqp(name){name=name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");var regexS="[\\?&]"+name+"=([^&#]*)";var regex=new RegExp(regexS);var results=regex.exec(window.location.href);if(results==null)return"";else return results[1];}
function setCookie(c_name,value,expiredays){var exdate=new Date();exdate.setDate(exdate.getDate()+expiredays);document.cookie=c_name+"="+escape(value)+((expiredays==null)?"":";expires="+exdate.toGMTString());}
function getCookie(c_name){if(document.cookie.length>0){c_start=document.cookie.indexOf(c_name+"=");if(c_start!=-1){c_start=c_start+c_name.length+1;c_end=document.cookie.indexOf(";",c_start);if(c_end==-1)c_end=document.cookie.length;return unescape(document.cookie.substring(c_start,c_end));}}return"";}
function include(filename){document.write(unescape("%3Cscript src='" + filename + "' type='text/javascript'%3E%3C/script%3E"));}


C. ADD LIVE TESTING FUNCTIONALITY
Some example code is shown below. The test URL parameter we're looking for is called "datalicious". So a URL like http://www.client-site.com/?datalicious=test will trigger the code to include from the test location instead of the production server. The default production code base is stored in a variable called "datClientCodebase"

var datURL=document.location.href.toLowerCase();
datTest = gqp('datalicious');
if (datTest == 'test') {
    setCookie('datCookie', 'test', 1);
}
if (datTest == 'client-name') {
    setCookie('datCookie', 'client-name', 1);
}
datCookieValue = getCookie('datCookie');
if (datCookieValue == 'test' || datTest == 'test' || datCookieValue == 'client-name' || datTest == 'client-name') {
    // This will use the test files on your server folder livetest
    if(datCookieValue == 'test' || datTest == 'test'){
        var datCodebase = '//www.your-server.com/client-name/js/livetest/';
    }else{
        // This will use the test files on the client-name server folder livetest
        var datCodebase = '//www.client-name.com.au/js/livetest/';
    }
} else {
    // Your server will use the production dir (this is done so you don't need a different file version on your
    //site), otherwise the client code base is used, which is the default normally
    if (datURL.indexOf('your-server.') > -1) {
        var datCodebase = '//www.your-server.com/client-name/js/';   
    } else {
        var datCodebase = datClientCodebase;   
    }
}

D. INCLUDE THE FILE
The following line of code takes the base file location and the file name (version), combines them and requests the desired file.

include(datCodebase + datScode);

E. TRIGGER
Now the file has been included, if there are any analytics functions, like with the Omniture scode, or google analytics page tracker, this part of the code can decide when these functions are executed. Normally we have conditions here so the function can be triggered at either the top or the bottom of the body.

F. CALL THE CONTROLLING FILE
Your web sites can now include this base file, but we recommend you use a cachebuster to ensure any updates you make the to base file propagate in a timely manner (we use 24 hours, but you can set to whatever you want). A code example is shown below, this would appear on all site pages:

<!-- BEGIN CACHE BUSTER -->
<script type="text/javascript">
var cacheBuster="";
var cbd=new Date();
var cbm=new Date();
var cby=new Date();
cbd=cbd.getUTCDate();
cbd=cbd.toString();
cbm=cbm.getUTCMonth()+1;
cbm=cbm.toString();
cby=cby.getUTCFullYear();
cby=cby.toString();
cacheBuster=cbd+":"+cbm+":"+cby;
</script>
<!-- END CACHE BUSTER -->

<!-- BEGIN INCLUDES -->
<script type="text/javascript">document.write('<scr'+'ipt type="text/javascript" src="//www.client-site.com/js/datalicious.js?cb='+cacheBuster+'"></scr'+'ipt>')</script>
<!-- END INCLUDES -->

Email Hamish at hogilvy@datalicious.com if you need help with your implementation.

Loading mentions Retweet
Email this post
Filed under  //   analytics   best practice   code   customization   google analytics   hamish   javascript   ogilvy   omniture   site catalyst   tips   web  
Posted by Hamish Ogilvy 

Comments [0]

IdeaChampion.com: 50 Ways to Foster a Culture of Innovation

Below are some great thought starters to plan for the new year, I especially like number 5, "make new mistakes".
  1. Remember that innovation requires no fixed rules or templates -- only guiding principles. Creating a more innovative culture is an organic and creative act.
  2. Wherever you can, whenever you can, always drive fear out of the workplace. Fear is "Public Enemy #1" of an innovative culture.
  3. Have more fun. If you're not having fun (or enjoying the process) something is off.
  4. Always question authority, especially the authority of your own longstanding beliefs.
  5. Make new mistakes.
  6. As far as the future is concerned, don't speculate on what might happen, but imagine what you can make happen.
  7. Increase the visual stimuli of your organization's physical space. Replace gray and white walls with color. Add inspiring photos and art, especially visuals that inspire people to think differently. Reconfigure space whenever possible.
  8. Help people broaden their perspective by creating diverse teams and rotating employees into new projects -- especially ones they are fascinated by.
  9. Ask questions about everything. After asking questions, ask different questions. After asking different questions, ask them in a different way.
  10. Ensure a high level of personal freedom and trust. Provide more time for people to pursue new ideas and innovations.

Read about the 40 remaining ways to foster innovation here
http://www.ideachampions.com/weblogs/archives/2009/12/50_ways_to_fost_1.shtml

Loading mentions Retweet
Email this post
Filed under  //   christian bartens   ideas   innovation   tips   trends  

Comments [1]

SEO Fix for session IDs using Google Webmaster Tools

Google has just added a function in Google Webmaster Tools that let’s you flag parameters you wish Google to ignore when crawling your site.

These can include things like session IDs, additional parameters and tracking ids. This is great way of handling the problem rather than forcing the webmaster to implement expensive work-around’s to be found in Google which has historically been the case.

Traditionally, sites that use session IDs as a way of tracking users or e-commerce, will have a disadvantage in search engine optimisation for a few reasons:

  • Duplicate content
  • Dispersion of page credit
  • Potential for bot to get tied up on these additional pages and not crawl other important pages as often

On the tracking front, and speaking from personal experience, flagging removal of tracking IDs is a big boost to data integrity. A recent campaign I worked on saw several blog and news site pick up a unique tracking URL to refer back to the clients site, a tracking ID that was meant to be unique for an email campaign. Google then decided to pick this URL up as it crawled through the sites and it ranked it well in search. The result was most of the search visitors appeared to the analytics system that they came from the email campaign and the collected data were significantly impacted.

Great news and makes life a lot easier for web masters and marketers stuck with this problem.

http://googlewebmastercentral.blogspot.com/2009/10/new-parameter-handling-tool-helps-with.html

Loading mentions Retweet
Email this post
Filed under  //   data integrity   google   google webmaster tools   seo   session IDs   tips   tools   tracking   webmaster tools  

Comments [2]

Video: how to visualize search term data using Wordle word clouds

Watch our video if you want to know how to create visualizations like this one below form Google search data.


http://screenr.com/6E7

Here are links to the used online tools.
https://adwords.google.com/select/KeywordToolExternal
http://www.wordle.net/advanced

Loading mentions Retweet
Email this post
Filed under  //   christian bartens   cloud   google   how to   search   terms   tips   tools   video   visualization   word   wordle  

Comments [0]

Social media measurement tips and tools

According to eMarketer's latest article social media measurement lags adoption among marketers which is quite sad considering the importance of social media in today's purchase or campaign funnel (see graph below). How a brand, service or product is portrayed in the social media space increasingly determines its overall success (e.g. Bruno launch) and can also be used as an early warning mechanism.

And it's really not that hard, the amount of free tools and advice that is available online to help with social media measurement is staggering. Have a look at the list of tools below plus the top 4 questions to ask yourself and don't hesitate to email Chris at cbartens@datalicious.com if you would like some further advice on how to measure social media success.


106743.gif

eMarketer: Social Media Measurement Lags Adoption
http://www.emarketer.com/Article.aspx?R=1007286


Brand Overviews

  • HowSociable? - A simple, free, tool that can measure the visibility of your brand on the web across 22 metrics
  • Addict-o-matic - A nice search engine that aggregates rss feeds, allowing you to quickly see the areas where a brand is lacking in presence
  • socialmention - A social media search engine offering searches across individual platforms (eg blogs, microblogs) or all, rates stength, sentiment, passion and reach, lists top authors

Blog Search Tools

  • TECHNORATI Search - Technorati's new search interface. Use it to find top blogs based upon inbound links only.
  • TECHNORATI Advanced - Technorati’s advanced search page allows you to search for blogs (rather than posts) based on tags.
  • Google Blog Search - Google's index of blog posts. The advanced search tab allows you to search based on additional criteria. Very good for searching between specific dates.
  • IceRocket - Blog search tool that also graph-ifies!
  • BlogPulse - Search for blog posts by keyword. Developed by Nielsen BuzzMetrics.

Buzz Tracking

  • Serph - Track buzz in real time
  • Google Trends - shows amount of searches and google news stories
  • Trendpedia - Create charts showing the volume of discussion around multiple topics. Generates cool graphs.
  • BlogPulse Trends - Compare the mentions of specific keywords and phrases in blog posts (LEFT vs. RIGHT)
  • Omgili Charts - Omgili Buzz Graphs let you measure and compare the Buzz of any term. Mostly from review sites/forums.
  • eKstreme - blog data is obtained from Technorati and the social bookmarks come from del.icio.us.

Message Board Search Tools

  • BoardTracker - tracks words in forums
  • BoardReader - Search multiple message boards and forums.
  • Omgili - Omgili is a specialized search engine that focuses on "many to many" user generated content platforms, such as, forums, discussion groups, mailing lists, answer boards and others. Omgili finds consumer opinions, debates, discussions, personal experiences, answers and solutions.
  • Google Groups - Searches usenet groups.
  • Yahoo! Groups - Searches all Yahoo! Groups.
  • Samepoint - Search Real-Time, Discussion Points, Bookmarks, Wikis, Q&A, Networks, and more

Twitter Search Tools

  • Twitter Search - Search keywords on Twitter which "self-refreshes". See what's happening — 'right now'.
  • Twitstat - Twitter Tweitgeist - Tag cloud for last 500 Tweets
  • TweetScan - search for words on Twitter
  • Twit(url)y - see what people are talking about on Twitter
  • Hashtags - Realtime Tracking of Twitter Hashtags
  • TweetBeep - Track mentions of your brand on Twitter in real time.
  • Twitrratr - Rates mentions of your search term on Twitter as positive/neutral/negative
  • TweetMeme - View the most popular Twitter threads occurring now.
  • TwitScoop – Through an automated algorithm, twitscoop crawls hundreds of tweets every minute and extracts the words which are mentioned more often than usual and creates a tag cloud.
  • Twilert - Twitter application that lets you receive regular email updates of tweets containing your brand, product, service.
  • Tweetcloud - Cloud of associated words around a submitted key word

For more tools and tips on social media measurement have a look at the below page.
http://measurementcamp.wikidot.com/tools-for-measurement

Where is the content coming from and how is it harvested?
Is the online content simply aggregated blog and board data from a handful of sources or does your provider harvest the data themselves? Is technology gathering the data or is there a human element to ensure important or relevant content sources are included? What tools are being used and how large is the content reservoir of CGM data? Does this reservoir contain current or historical data, or both?

How is the data cleaned and prepared?
How does your data provider clean and prepare the data for analysis? What rules are applied to systematically reduce irrelevant conversations (noise) and ensure relevance? For example, if you are interested in CGM insights on the telecommunications provider 'Orange', how do they ensure references to orange as a fruit or colour are excluded?

How is the data organized or segmented?
Is the remaining content relevant to the business questions being asked? What are the base, volume and discussion sources being included for classification? How is the data being segmented so it contains the most pertinent consumer discussions around your specific area of interest?

How is the data being analysed and are actionable insights delivered?
How is the information actually being analysed? Is it purely done by automated technology or by human analysis, or both? If technologies and software provide the information, how does this technology manage to measure things like sentiment of a conversation accurately? Can technologies help you determine what the important topics are that lead volume or drive a particular sentiment? Is there a consulting service so that information and data can be transformed into insight?

Check out the below page for the full article.
http://server-uk.imrworldwide.com/pdcimages/NielsenOnline_May_Newsletter08.html

Loading mentions Retweet
Email this post
Filed under  //   analytics   christian bartens   measurement   media   social   tips   tools  

Comments [0]

Top five tips for deploying Omniture Site Catalyst Javascript

Below are some pretty basic tips to Site Catalyst setup, they may seem straight forward, but i am continually surprised at how poorly Omniture is set up, so maybe they're not so obvious!

1. Have one scode file

Duplicating the scode file is painful and you will eventually make mistakes. Keep all your code in one file.

2. Use a cachebuster

This will ensure your javascript code updates propagate quickly. Otherwise your existing users may not reflect the changes, which can complicate and confuse reporting. A cachebuster automatically adds a parameter to the end of the javascript file reference, which forces it to be reloaded. i.e. scode.js?cb=1234

3. Make it protocol independent

Don't put "http:" in your file reference, this will allow the javascript to work for either http or https. i.e src="//www.example.com/js/scode.js"

4. Use the s.pageName variable properly
This is by far the most important thing to set, i can't even stress that enough. Any extra effort to get it right is worth it. Your pageName should preferably follow a set structure so your javascript can utilise it fully. If you get this right, your reports will immediately become more powerful. We typically follow a structure like the following:
site:sub-section:sub-sub-section:sub-sub-sub-section

This should follow the site directory structure where possible. i.e. www.site.com/sub-section/sub-sub-section/sub-sub-sub-section

By breaking this up and putting it into several props and eVars, you will be able to look at success events at a site, sub section, sub sub section and sub sub sub section level, which is very useful. You will also be able to trigger certain events based on these values. Code example below, which should also be copied from props to eVars:

var scSection=s.split(s.pageName,':');
s.prop1 = scSection[0];
if (typeof scSection[1] != 'undefined')
s.prop2 = s.prop1 + ":" + scSection[1];
if (typeof scSection[2] != 'undefined')
s.prop3 = s.prop2 + ":" + scSection[2];
if (typeof scSection[3] != 'undefined')
s.prop4 = s.prop3 + ":" + scSection[3];


The output of the above will be:
s.prop1 = site
s.prop2 = site:sub-section
s.prop3 = site:sub-section:sub-sub-section
s.prop4 = site:sub-section:sub-sub-section:sub-sub-sub-section

5.
Minimise the on page javascript
Any logic you can use to trigger events based on the pageName, the URL or section variables, will make things so much easier. If you can get code off the individual pages and keep all the logic in the scode file, you will greatly simplify any deployments and rollbacks. For some things you can't avoid putting code on individual pages, but it's suprising how often it can be avoided.

An example might be a segmentation rule that will label someone once they have stayed for at least 2 pages in a particular site section. For things like this, very small changes to the scode can be very powerful, if you paid attention to tip 1 above, they're also immediately site wide!

If you need help with your implementation, email Hamish at hogilvy@datalicious.com.

Loading mentions Retweet
Email this post
Filed under  //   analytics   code   customisation   hamish   javascript   ogilvy   omniture   scode   site catalyst   tips   web  
Posted by Hamish Ogilvy 

Comments [7]