<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8794092920201977674</id><updated>2010-03-27T19:17:17.186-07:00</updated><title type='text'>Website Optimizer Tricks</title><subtitle type='html'></subtitle><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8794092920201977674/posts/default'/><link rel='alternate' type='text/html' href='http://www.gwotricks.com/default.htm'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.gwotricks.com/atom.xml'/><author><name>Eric Vasilik</name><uri>http://www.blogger.com/profile/09622601499428032516</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>9</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8794092920201977674.post-4950920749853573445</id><published>2050-01-30T13:35:00.000-08:00</published><updated>2009-07-19T22:28:05.440-07:00</updated><title type='text'>Website Optimizer Tricks Index</title><content type='html'>&lt;p&gt;Current Articles:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.gwotricks.com/2009/01/multiple-goals.html"&gt;&lt;span style="font-weight: bold;"&gt;Multiple Goals&lt;/span&gt;&lt;/a&gt; - Test more than one goal by creating multiple experiments for the same test!&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.gwotricks.com/2009/02/poor-mans-gwoanalytics-integration.html"&gt;&lt;span style="font-weight: bold;"&gt;GA Integration&lt;/span&gt;&lt;/a&gt; - Get experiment information into GA. &lt;/li&gt;&lt;li&gt;&lt;a href="http://www.gwotricks.com/2009/02/where-does-control-script-belong.html"&gt;&lt;span style="font-weight: bold;"&gt;Control Script Placement&lt;/span&gt;&lt;/a&gt; - Where should you place the control script in your test page?&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.gwotricks.com/2009/02/advanced-ab-experiments.html"&gt;&lt;span style="font-weight: bold;"&gt;Advanced A/B Experimentation&lt;/span&gt;&lt;/a&gt; - Techniques for obtaining more control or A/B redirection.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.gwotricks.com/2009/03/advanced-test-page-functionality.html"&gt;&lt;span style="font-weight: bold;"&gt;Advanced Test Page Functionality&lt;/span&gt;&lt;/a&gt; - Functionality for writing customized tests. &lt;/li&gt;&lt;li&gt;&lt;a href="http://www.gwotricks.com/2009/04/fragmented-sections.html"&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;&lt;a href="http://www.gwotricks.com/2009/04/fragmented-sections.html"&gt;Fragmented Sections&lt;/a&gt;&lt;/strong&gt; - Test non-contiguous pieces of your page with Fragmented Sections.&lt;strong&gt;&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.gwotricks.com/2009/04/fragmented-sections.html"&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;&lt;a href="http://www.gwotricks.com/2009/05/server-side-dynamic-section-variations.html"&gt;Server-Side Dynamic Section Variations&lt;/a&gt;&lt;/strong&gt; - How to generate dynamic section variations on your web server.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;New! &lt;a href="http://www.gwotricks.com/test/2009/07/tracking-outbound-links-right-way.html"&gt;Tracking Outbound Links -- The Right Way&lt;/a&gt;&lt;/strong&gt; - How to correctly track outbound links&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Future Articles: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Client-Side Dynamic Section Variations&lt;/strong&gt; - How to include dynamic content in a section.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Techniques for Debugging Experiments&lt;/strong&gt; - How to check to see if your experiment is running properly.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8794092920201977674-4950920749853573445?l=www.gwotricks.com%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/8794092920201977674/4950920749853573445/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8794092920201977674&amp;postID=4950920749853573445' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8794092920201977674/posts/default/4950920749853573445'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8794092920201977674/posts/default/4950920749853573445'/><link rel='alternate' type='text/html' href='http://www.gwotricks.com/2009/01/website-optimizer-tricks-index.html' title='Website Optimizer Tricks Index'/><author><name>Eric Vasilik</name><uri>http://www.blogger.com/profile/09622601499428032516</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09933651237686075846'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8794092920201977674.post-6158635136096159571</id><published>2009-07-19T22:22:00.001-07:00</published><updated>2009-08-11T12:56:36.254-07:00</updated><title type='text'>Tracking Outbound Links -- The Right Way</title><content type='html'>&lt;p&gt;Let's say you want to run an experiment on a page in the &lt;b&gt;foo.com&lt;/b&gt; domain, but you want to &lt;br /&gt;register conversions in some outbound domain, say, &lt;b&gt;bar.com&lt;/b&gt;.  One way to handle this is to implement a&lt;br /&gt;strategy called &lt;i&gt;Google Analytics Cross Domain Linking&lt;/i&gt; as described in this &lt;a href="http://www.google.com/support/analytics/bin/answer.py?hl=en&amp;answer=55503"&gt;Analytics Help Center Article&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;This is a fine solution, but it suffers from two major problems.  First, it requires that you have the rights to modify pages in the outbound domain.  Secondly, and frankly (IMHO), it's kinda a pain in the ass to implement as well as being very error prone.  &lt;br /&gt;&lt;br /&gt;An alternative to tracking the loading of the outbound page, is to track the user's action of clicking the link to the outbound page.  This is neatly described in this &lt;a href="http://www.google.com/support/analytics/bin/answer.py?hl=en&amp;answer=55527"&gt;Analytics Help Center Article&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The only problem with this technique is that it really does not work very well.  It suffers from what we in the industry call a &lt;a href="http://en.wikipedia.org/wiki/Race_condition"&gt;Race Condition&lt;/a&gt;.  To understand this particular race condition, allow me to describe a little about how browsers work.&lt;br /&gt;&lt;br /&gt;When a web browser is loading a page and it encounters something like the following:&lt;br /&gt;&lt;pre&gt;&lt;div class=mycode&gt;... la la la&lt;br /&gt;&amp;lt;img src="a.jpg"&gt;&lt;br /&gt;la te da ...&lt;/div&gt;&lt;/pre&gt;The browser does not stop at the image tag in order to load the image.  In fact it does not even stop at the image tag to even &lt;i&gt;start&lt;/i&gt; loading the image.  It simply queues up a request to load that image at some later time.  Later in this case means really quick; probably in the next few milliseconds.  It may do this with another thread, or simply schedule it within the same thread.  The important point is that the HTTP request to the server which services the image &lt;i&gt;does not take place right away&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Now, consider the following HTML:&lt;pre&gt;&lt;div class=mycode&gt;... One two three&lt;br /&gt;&amp;lt;a href="target.htm"&gt;Click Me!&amp;lt;/a&gt;&lt;br /&gt;... four five six ...&lt;/div&gt;&lt;/pre&gt;Here, when a visitor clicks on this link, the mechanism for loading and displaying the target page is very similar to the loading of the image above.  A request to start loading that page is queued up, and when the bytes of that response start arriving, the browser erases the current page and starts rendering the new page.  This is why after clicking on a link to a "distant" and slow site, you will continue to see the current page until the other responds -- there is no good reason to clear the screen on the current page until you have something new to display.&lt;br /&gt;&lt;br /&gt;One more vital piece of information needs to be mentioned here.  When a page is closed, in this case in favor of loading a new page, all the outstanding resource requests for the current, closing, page (like images) are abandoned.  This fact will place a crucial role in our race condition.&lt;br /&gt;&lt;br /&gt;Now, let's look at the code mentioned in the &lt;a href="http://www.google.com/support/analytics/bin/answer.py?hl=en&amp;answer=55527"&gt;How do I manually track clicks on outbound links?&lt;/a&gt; article:&lt;pre&gt;&lt;div class=mycode&gt;&amp;lt;a href="http://www.example.com" onClick="javascript: pageTracker._trackPageview('/outgoing/example.com');"&gt;&lt;/div&gt;&lt;/pre&gt;The script in the &lt;b&gt;onClick&lt;/b&gt; handler is intended to create a Google Analytics event (called /outgoing/example.com) with the &lt;b&gt;_trackPageview&lt;/b&gt; operation.  The way that _trackPageview works is that it makes a request to Google for an, essentially, empty image.  Along with that request, is the information about the visitor and what should be tracked.  It's how Google Analytics gets its information in order to create reports.  Now, just like the loading of an image tag, this request is also queued up by the browser -- &lt;i&gt;It's not immediately requested&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Once the call to _trackPageview returns, the browser then starts the request for the outbound resource, "http://www.example.com", in this case.  This too is queued up, and when it start to come in, the page will clear and the new page will be rendered.&lt;br /&gt;&lt;br /&gt;Now, we have enough information to see where the race condition exists.&lt;br /&gt;&lt;br /&gt;If the request for example.com comes back really quickly, it is quite possible that the request for the Google Analytics tracking image has not yet taken place.  In fact, some browsers may prioritize requests for images below other requests, like those for other sites.  When this happens, all outstanding resource requests for the current page, and I'm thinking about the Google Analytics tracking request in particular, are abandoned.  This means that the event which was to be tracked via Analytics is lost to Analytics, as though it never happend.&lt;br /&gt;&lt;br /&gt;Bummer.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Give It Some Time ...&lt;/h3&gt;&lt;br /&gt;So, how does one track outbound links properly?&lt;br /&gt;&lt;br /&gt;The trick is to give the request for the Google Analytics tracking image enough time to take place.  This can be done by delaying the request for the outbound page with the following technique:&lt;pre&gt;&lt;div class=mycode&gt;&amp;lt;script type="text/javascript"&gt;&lt;br /&gt;function doGoal(that) {&lt;br /&gt;  try {&lt;br /&gt;    var pageTracker=_gat._getTracker("UA-123456-1");&lt;br /&gt;    pageTracker._trackPageview("http://www.example.com");&lt;br /&gt;    &lt;span class=code_bold&gt;setTimeout&lt;/span&gt;('document.location = "' + that.href + '"', 100)&lt;br /&gt;  }catch(err){}&lt;br /&gt;}&lt;br /&gt;&amp;lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;a href="www.example.htm" onclick='doGoal(this);&lt;span class=code_bold&gt;return false&lt;/span&gt;;'&gt;Click me&amp;lt;/a&gt;&lt;/div&gt;&lt;/pre&gt;Here, notice that the onClick handler calls a function which, first, does not rely on the presence of a global pageTracker object to have been already set up.  It creates it's own tracking object.  This reduces the dependency on other scripts running on the page.&lt;br /&gt;&lt;br /&gt;Secondly, the return value from the onClick handler is &lt;b&gt;false&lt;/b&gt;.  This prohibits the browser from following the link as a consequence of the user clicking on the link.  This stops the browser from immediately navigating to example.com.&lt;br /&gt;&lt;br /&gt;Thirdly, notice the call to the &lt;b&gt;setTimeout&lt;/b&gt; function.  The setTimeout function's job is to execute a piece of code at some time in the future, without blocking the current script from continuing executing.  In this case, it's 1/10 of a second into the future, and the code to execute is that which is, essentially, the same as what the browser would have done if &lt;b&gt;true&lt;/b&gt; (or nothing) had been returned by the onClick handler.  Setting the location property of the document object with the outbound href will cause the page to navigate to that link.&lt;br /&gt;&lt;br /&gt;By delaying the outbound navigation by 1/10 of a second (which is generally not noticed by the user), the browser now has much more time to make the Google Analytics tracking request and the tracking event will be noticed and reported on by Google Analytics.&lt;br /&gt;&lt;br /&gt;Spiffy.&lt;br /&gt;&lt;br /&gt;The example above applies to tracking outbound links in Analytics, and is trivially adapted to tracking Google Website Optimizer goals as well.  You can see an example of a test page taking advantage of this technique &lt;a href="http://www.gwotricks.com/clickgoal/testpage.htm"&gt;here&lt;/a&gt; to track as the goal, clicking on a link.&lt;br /&gt;&lt;br /&gt;The essential code in the GWO sample page follows.  All that is really different is that the argument to _trackPageview is the token string for the GWO goal.&lt;pre&gt;&lt;div class=mycode&gt;&amp;lt;script type="text/javascript"&gt;&lt;br /&gt;function doGoal(that) {&lt;br /&gt;  try {&lt;br /&gt;    var pageTracker=_gat._getTracker("UA-7250447-1");&lt;br /&gt;    pageTracker._trackPageview(&lt;span class=code_bold&gt;"/2353623095/goal"&lt;/span&gt;);&lt;br /&gt;    setTimeout('document.location = "' + that.href + '"', 100)&lt;br /&gt;  }catch(err){}&lt;br /&gt;}&lt;br /&gt;&amp;lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;a href="anotherpage.htm" onclick='doGoal(this);return false;'&gt;Click me&amp;lt;/a&gt;&lt;/div&gt;&lt;/pre&gt;&lt;br /&gt;Happy Clicking!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8794092920201977674-6158635136096159571?l=www.gwotricks.com%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/8794092920201977674/6158635136096159571/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8794092920201977674&amp;postID=6158635136096159571' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8794092920201977674/posts/default/6158635136096159571'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8794092920201977674/posts/default/6158635136096159571'/><link rel='alternate' type='text/html' href='http://www.gwotricks.com/2009/07/tracking-outbound-links-right-way.html' title='Tracking Outbound Links -- The Right Way'/><author><name>Eric Vasilik</name><uri>http://www.blogger.com/profile/09622601499428032516</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09933651237686075846'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8794092920201977674.post-5075169185355175708</id><published>2009-05-19T01:07:00.001-07:00</published><updated>2009-05-27T21:16:02.507-07:00</updated><title type='text'>Server-Side Dynamic Section Variations</title><content type='html'>&lt;p&gt;This technique is one of my favorites because it involves some pretty "clever" (euphemism for twisted) JavaScript.  But don't let this scare you, the script works on all the browsers and is as fail-safe as the scripting that Website Optimizer requests you place on your sites by default.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;h3&gt;Multi-Variate Experiments "Out of the Box"&lt;/h3&gt;&lt;br /&gt;First, let's revisit certain aspects of GWO pertinent to this technique.  By default, GWO handles multi-variate experiments in the following way:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.gwotricks.com/2009/05/default.png" /&gt;&lt;br /&gt;&lt;br /&gt;Your test page and the default content for your experiment sections are served directly from your web server.  If alternative content has been chosen to be displayed to a visitor, that alternative content is served from a Google server.&lt;br /&gt;&lt;br /&gt;Now, this poses a particular limitation: the alternative content must be static in nature.  The reason behind this is in the fact that, in the default setup process of a multi-variate experiment, you are requested to input the alternative content into GWO's user interface, and that content is simply served back to your test page on demand where it replaces the default content in the page for visitors selected to see the alternative content.&lt;br /&gt;&lt;br /&gt;This means that if you wanted to customize that alternative content differently for each visitor, you don't get a chance to do so.  For example, you might want to include the customer's name in the alternative content.  Or, you might want to serve a promotion customized for the given customer.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Alternative Content Served from Your Webserver&lt;/h3&gt;&lt;br /&gt;The technique I am about to discuss allows you to serve all content, default and alternative, directly from your web server:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.gwotricks.com/2009/05/dynserver.png" /&gt;&lt;br /&gt;&lt;br /&gt;Here, the Google server does not serve any alternative content.  It only serves back an indicator (an integer) of which content should be show to a given visitor.  All the possible variations for the sections are rendered into the web page by your web server where you have complete dynamic control over the content of those variations.  In the following, I will show you the scripts you need to generate along with that content in order to show one of either your default content or variations.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Size of Alternatives&lt;/h3&gt;&lt;br /&gt;That said, one should be careful when using this technique because it requires you to render all possible section variations into the page.  Because even though your web server knows what the content of the alternatives are, it does not know which alternative will be chosen for a visitor to your test page.  Contact with the Google server is required for that, and the logic about which content to show to the visitor must be executed in the browser client.&lt;br /&gt;&lt;br /&gt;So, if the number and size of all the alternative section variations is not too large, you can use this technique.  Many times, this is the case.  Even if you define your entire page to be a single section, this technique may work for you because only the HTML of the alternative need be present in your page.  Any other resources, like images, scripts or style sheets, which are specific to an alternative variation will be loaded if that alternative variation is chosen for a visitor.  Content which was not chosen for the visitor will not even be parsed by the browser, it will essentially be thrown away.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Creating the Experiment&lt;/h3&gt;&lt;br /&gt;To use this technique, you begin by creating a regular multi-variate experiment.  Give the experiment a name, test page and goal page.  When asked to add the GWO scripts to the page, add the control script in the normal way.  And, add the tracking scripts in the normal way.&lt;br /&gt;&lt;br /&gt;However, do not follow the default instructions for adding section scripts.  I have prepared an example test page you can look at which illustrates the alternative to the default section scripts which allows you to serve alternative section variations from your web server:&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;&lt;a href="http://www.gwotricks.com/dynserver/testpage.htm"&gt;Server Side Sections Example&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;First, you will want to declare the number and names of the server-side dynamic experiment sections you plan to test.  Sections are normally declared as a result of surrounding the default content of a section with the standard GWO sections scripts.  But, because we are not using those, you need to use an alternative.  So, to declare a single section with the name "Section1", place the following immediately after the Control Script:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;div class="mycode"&gt;&amp;lt;!-- utmx section name="Section1" --&amp;gt;&lt;/div&gt;&lt;/pre&gt;You can repeat this kind of comment to declare up to 8 sections.  For example:&lt;br /&gt;&lt;pre&gt;&lt;div class="mycode"&gt;&amp;lt;!-- utmx section name="Section1" --&amp;gt;&lt;br /&gt;&amp;lt;!-- utmx section name="Section2" --&amp;gt;&lt;br /&gt;&amp;lt;!-- utmx section name="Section3" --&amp;gt;&lt;/div&gt;&lt;/pre&gt;&lt;br /&gt;Note that you can mix regular GWO multi-variate section with server-side dynamic sections.  Simply include the standard GWO style sections as described in the default install instructions.&lt;br /&gt;&lt;h3&gt;Instrumenting the Sections&lt;/h3&gt;&lt;br /&gt;The following script is the entire definition of the section from my example page.  I show you in its entirety here, and will dissect it later.  Note that the dynamic content for each variation is highlighted.  These are the parts of the page you get to dynamically generate.  Only one of them will be show to a given visitor, the others will be stripped away.&lt;br /&gt;&lt;pre&gt;&lt;div class="mycode"&gt;&amp;lt;script&amp;gt;&lt;br /&gt;var GWO_Section1 = utmx("variation_number", "Section1");&lt;br /&gt;if (GWO_Section1 != undefined &amp;amp;&amp;amp; GWO_Section1 != 0) document.write('&amp;lt;no' + 'script&amp;gt;');&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;span class="code_bold"&gt;Original content - shown by default&amp;lt;br&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;lt;/noscript&amp;gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&amp;lt;script&amp;gt;&lt;br /&gt;if (GWO_Section1 == 1) document.write('&amp;lt;/noscript a="');&lt;br /&gt;&amp;lt;/script&amp;gt;&amp;lt;!--"&amp;gt;&lt;br /&gt;&lt;span class="code_bold"&gt;Alternative content 1&amp;lt;br&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;lt;script&amp;gt;document.write('&amp;lt;'+'!'+'-'+'-')&amp;lt;/script&amp;gt;--&amp;gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&amp;lt;script&amp;gt;&lt;br /&gt;if (GWO_Section1 == 2) document.write('&amp;lt;/noscript a="');&lt;br /&gt;&amp;lt;/script&amp;gt;&amp;lt;!--"&amp;gt;&lt;br /&gt;&lt;span class="code_bold"&gt;Alternative content 2&amp;lt;br&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;lt;script&amp;gt;document.write('&amp;lt;'+'!'+'-'+'-')&amp;lt;/script&amp;gt;--&amp;gt;&lt;/p&gt;&lt;/div&gt;&lt;/pre&gt;The basic idea with this technique is that each of these script blocks controls a piece of content.  The first controls the original content.  By default, the original content is show to the visitor.  The other script blocks control the alternative pieces of content, one of which, is meant to replace the original content.  By default the alternatives are hidden from the visitor.  If an alternative is chosen to be shown to the visitor, then the script blocks will work together to hide the original and show only one of the alternatives to the visitor.&lt;br /&gt;&lt;br /&gt;The content contained in each of these script blocks is totally under your control in your web server.  Which one of them is shown to the visitor is under the control of Website Optimizer.&lt;br /&gt;&lt;h3&gt;The Default Content&lt;/h3&gt;&lt;br /&gt;Like any GWO experiment, the default content is encoded in your test pages, and if JavaScript is not present or disabled, or there is any malfunction anywhere, the default content will be presented to your visitors.  With this technique, the default content is handled with this script:&lt;br /&gt;&lt;pre&gt;&lt;div class="mycode"&gt;&amp;lt;script&amp;gt;&lt;br /&gt;var GWO_Section1 = utmx("variation_number", "Section1");&lt;br /&gt;if (GWO_Section1 != undefined &amp;amp;&amp;amp; GWO_Section1 != 0) document.write('&amp;lt;no' + 'script&amp;gt;');&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;span class="code_bold"&gt;Original content - shown by default&amp;lt;br&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;lt;/noscript&amp;gt;&lt;br /&gt;&lt;/div&gt;&lt;/pre&gt;Here, the script code firsts obtains the number of the variation for the section named "Section1" chosen for the current visitor:&lt;br /&gt;&lt;pre&gt;&lt;div class="mycode"&gt;var GWO_Section1 = utmx("variation_number", "Section1");&lt;/div&gt;&lt;/pre&gt;This call to the utmx function will return a &lt;b&gt;0&lt;/b&gt; (zero) or &lt;b&gt;undefined&lt;/b&gt; if the visitor should see the default content.  This value is saved in a global variable for use in subsequent alternative content scripts.  Note that the &lt;b&gt;utmx&lt;/b&gt; function is defined by the Control Script which needs to have been executed before the call to the utmx function in this script.&lt;br /&gt;&lt;br /&gt;Then, if alternative content has been chosen for this visitor, the default content is hidden from the visitor with the second line of code:&lt;pre&gt;&lt;div class="mycode"&gt;if (GWO_Section1 != undefined &amp;amp;&amp;amp; GWO_Section1 != 0) document.write('&amp;lt;no' + 'script&amp;gt;');&lt;/div&gt;&lt;/pre&gt;By document.writing a beginning &lt;b&gt;&amp;lt;noscript&amp;gt;&lt;/b&gt; tag, the content after the script and up to the first &lt;b&gt;&amp;lt;/noscript&amp;gt;&lt;/b&gt; tag will be consumed and ignored by the parser.  This requires that your default content not contain any noscript tags (beginning or ending).  This is exactly the same technique used by GWO for standard installations of multi-variate experiments.  The only difference is that here we are just removing the default content, but the standard GWO multi-variate technique document.writes the alternative content to replace the default content before writing the &lt;b&gt;&amp;lt;noscript&amp;gt;&lt;/b&gt; tag to eliminate the default content.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The Alternative Content&lt;/h3&gt;&lt;br /&gt;Now, for each variation of alternative content for a given section, you will need a script like this:&lt;br /&gt;&lt;pre&gt;&lt;div class="mycode"&gt;&amp;lt;script&amp;gt;&lt;br /&gt;if (GWO_Section1 == &lt;span class="code_bold"&gt;1&lt;/span&gt;) document.write('&amp;lt;/noscript a="');&lt;br /&gt;&amp;lt;/script&amp;gt;&amp;lt;!--"&amp;gt;&lt;br /&gt;&lt;span class="code_bold"&gt;Alternative content 1&amp;lt;br&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;lt;script&amp;gt;document.write('&amp;lt;'+'!'+'-'+'-')&amp;lt;/script&amp;gt;--&amp;gt;&lt;/div&gt;&lt;/pre&gt;Note that the &lt;b&gt;1&lt;/b&gt; indicates that this script is customized for the first alternative.  The second alternative will have the number &lt;b&gt;2&lt;/b&gt;, the third &lt;b&gt;3&lt;/b&gt;, etc.  The larger highlighted part is your dynamically generated alternative content for the first alternative.  Simply have your web server surround the alternative content with the other text.&lt;br /&gt;&lt;br /&gt;The first line of the script determines if this alternative was chosen to be viewed by the visitor and document.writes some content designed to cause the variation to be shown to the visitor:&lt;pre&gt;&lt;div class="mycode"&gt;if (GWO_Section1 == 1) document.write('&amp;lt;/noscript a="');&lt;/div&gt;&lt;/pre&gt;To understand this better, consider what this content would look like if scripting is disabled, or the value of &lt;b&gt;GWO_Section1&lt;/b&gt; does not have the value &lt;b&gt;1&lt;/b&gt;.  That is, there is no script:&lt;br /&gt;&lt;pre&gt;&lt;div class="mycode"&gt;&amp;lt;!--"&amp;gt;&lt;br /&gt;Alternative content 1&amp;lt;br&amp;gt;&lt;br /&gt;&amp;lt;script&amp;gt;document.write('&amp;lt;'+'!'+'-'+'-')&amp;lt;/script&amp;gt;--&amp;gt;&lt;/div&gt;&lt;/pre&gt;This entire block of HTML is nothing more than one large comment.  In fact, the alternative content is hidden by default by the fact that it is embedded inside a comment.  This means that the alternative content &lt;i&gt;must not have any comments&lt;/i&gt; in it.  Note that even the script at the end of the HTML is also inside the comment.&lt;br /&gt;&lt;br /&gt;Now, look carefully at what is written if this section variation has been chosen to be displayed to the visitor:&lt;br /&gt;&lt;pre&gt;&lt;div class="mycode"&gt;&amp;lt;/noscript a="&lt;/div&gt;&lt;/pre&gt;This is the beginning of an ending noscript tag.  Note that there is no &lt;b&gt;&amp;gt;&lt;/b&gt; terminating the tag.  Also, in this tag there is the beginning of an attribute.  Notice, also, that the value of the attribute is not present and that the ending double quote is not present.  That is not two single quotes.  It is a single double quote.&lt;br /&gt;&lt;br /&gt;Recall that the way that document.write works is that the written text is, essentially, inserted after the end of the script where the browser parser will resume its parsing after the script has executed.  Again, by stripping away the first script tag, let's look at what the parser will encounter:&lt;br /&gt;&lt;pre&gt;&lt;div class="mycode"&gt;&amp;lt;/noscript a="&amp;lt;!--"&amp;gt;&lt;br /&gt;Alternative content 1&amp;lt;br&amp;gt;&lt;br /&gt;&amp;lt;script&amp;gt;document.write('&amp;lt;'+'!'+'-'+'-')&amp;lt;/script&amp;gt;--&amp;gt;&lt;/div&gt;&lt;/pre&gt;Here the parser sees an ending noscript tag with an attribute whose value are the characters which begin a comment.  The thing to know here is that HTML parsers allow beginning comment sequences inside attribute values.  This is the clever (twisted) part I eluded to earlier.&lt;br /&gt;&lt;br /&gt;Now, it should be apparent why there was the &lt;span class="code_bold"&gt;"&amp;gt;&lt;/span&gt; characters immediately after the beginning comment character sequence: &lt;span class="code_bold"&gt;&amp;lt;!--&lt;/span&gt;.  It is there to terminate the dynamically written ending noscript tag.  This tag "eats" the beginning comment token.  Yummy.&lt;br /&gt;&lt;br /&gt;This allows the parser to parse and display the alternative content.  Now, all we need to do is deal with the remaining ending comment token!  This is done by the last part of the script:&lt;br /&gt;&lt;pre&gt;&lt;div class="mycode"&gt;&amp;lt;script&amp;gt;document.write('&amp;lt;'+'!'+'-'+'-')&amp;lt;/script&amp;gt;&lt;/div&gt;&lt;/pre&gt;Which injects a beginning comment token which is terminated by the remaining ending comment token, statically present in the page.  Without this document.write, the "&lt;b&gt;--&amp;gt;&lt;/b&gt;" would appear in the page when this alternative content was chosen for the visitor.&lt;br /&gt;&lt;br /&gt;This is how each alternative variation is handled.  Simply do the above for each alternative section.  Each one will have the server generated content of the variation.  Each script will have the number of the variation encoded in it.  1 for the first alternative, 2 for the second, etc.&lt;br /&gt;&lt;br /&gt;You can repeat this sequence of scripts for a section as many times on your page(s) as you want to hide/show the default/alternative content for that section.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Setting Up the Variations in GWO&lt;/h3&gt;&lt;br /&gt;Even though this technique requires you generate all your alternative content into the page, you will still need to create section variations in Step 3 of the GWO user interface for each section in your test.  The only difference is that you do not supply any content for these variations.  The reason for this is that GWO still needs to know how many variations each server-side dynamic section has for the purposes of choosing which variation visitors will see and reporting results.  For example:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.gwotricks.com/2009/05/step3.png" /&gt;&lt;br /&gt;&lt;br /&gt;Shows the section named "Section1" with two (2) variations created for it.  I give each variation a name for reporting purposes, but I do not need to give it any content.&lt;br /&gt;&lt;br /&gt;After Doing this, all that is left to do is preview the experiment to make sure the scripts are working and launch the experiment!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8794092920201977674-5075169185355175708?l=www.gwotricks.com%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/8794092920201977674/5075169185355175708/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8794092920201977674&amp;postID=5075169185355175708' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8794092920201977674/posts/default/5075169185355175708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8794092920201977674/posts/default/5075169185355175708'/><link rel='alternate' type='text/html' href='http://www.gwotricks.com/2009/05/server-side-dynamic-section-variations.html' title='Server-Side Dynamic Section Variations'/><author><name>Eric Vasilik</name><uri>http://www.blogger.com/profile/09622601499428032516</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09933651237686075846'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8794092920201977674.post-6997587915231359211</id><published>2009-04-09T22:29:00.000-07:00</published><updated>2009-04-11T23:58:20.255-07:00</updated><title type='text'>Test non-contiguous pieces of your page with Fragmented Sections</title><content type='html'>&lt;p&gt;&lt;br /&gt;The default setup for a multi-variate experiment asks you to place what are called "Section Tags" on your test page. For example consider a header for a fictitious pet food web site:&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;div class="mycode"&gt;&lt;span class="code_bold"&gt;&amp;lt;script&gt;utmx_section('Heading')&amp;lt;/script&gt;&lt;/span&gt;&lt;br /&gt;World's best pet food!&lt;br /&gt;&lt;span class="code_bold"&gt;&amp;lt;/noscript&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/pre&gt;The purpose of these tags is to identify a contiguous span of HTML on your test page with which you would like to experiment. In the GWO online tool, you would enter the alternative variations for this section. For example:&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;img src="http://www.gwotricks.com/2009/04/normal.png" /&gt;&lt;/center&gt;&lt;br /&gt;&lt;p&gt;This allows you to specify an alternative which will replace the original content on your test page. In fact, everywhere this pet food website mentions the phrase "World's best pet food!", you could instrument that phrase with the scripts above to have a visitor to your site experience every instance of the phrase on the site with the &lt;b&gt;same&lt;/b&gt; alternative variation.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;But, what if you want to vary multiple parts of a page (or pages) on your site in concert with each other? For example, let's say that our fictitious pet food web site shows a letter to visitors, like so:&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;center&gt;&lt;img src="http://www.gwotricks.com/2009/04/original.png" border="1" /&gt;&lt;/center&gt;&lt;br /&gt;&lt;p&gt;Then let's say that you want to have multiple variations of the letter, each with a different tone in the salutation and signature. For example, an informal tone:&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;center&gt;&lt;img src="http://www.gwotricks.com/2009/04/informal.png" border="1" /&gt;&lt;/center&gt;&lt;br /&gt;&lt;p&gt;Or, a formal tone:&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;center&gt;&lt;img src="http://www.gwotricks.com/2009/04/formal.png" border="1" /&gt;&lt;/center&gt;&lt;br /&gt;&lt;p&gt;Now, you could implement this in the same manner as the section shown above. However, because the salutation and signature are separated by the body of the letter, you would have to include an entire copy of the body in each variation of the section, where the different variations differ only by the salutation at the beginning and the corresponding signature at the end.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Now, in this simple example the body is not that large, but the redundancy runs the risk of introducing different bodies which would foil the experiment. And, in the case where the body is not small, you would not want to replicate the body. Furthermore, it might be the case that the two parts of your site you want to vary in concert with each other are not on the same page. The standard section tagging technique breaks down entirely in this case.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The technique I am about to explain will allow you to experiment with your site in such a way as to only require you to alter the actual pieces of the page you want to change, but allow you to have those pieces change together. This is what I call &lt;i&gt;Fragmented Sections&lt;/i&gt;. First, a look at what you would enter into the GWO online tool for a variation of our letter's Tone section:&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;center&gt;&lt;img src="http://www.gwotricks.com/2009/04/fragmented.png" /&gt;&lt;/center&gt;&lt;br /&gt;&lt;p&gt;What I've done here is to place what I call &lt;b&gt;Fragments&lt;/b&gt; of a single section variation surrounded by special %% tokens which identify the fragments with monotonically increasing numbers starting with 1 (fragments cannot have %% sequences in them, or a different token will need to be chosen). Thus, the salutation (the first fragment) of the Formal variation of the Tone section is represented by:&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="mycode"&gt;%%Frag 1%%Dear Sir/Madam%%&lt;/div&gt;&lt;br /&gt;and the signature (the second fragment) is represented by:&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;%%Frag 2%%Sincerely%%&lt;/div&gt;&lt;br /&gt;The value for the informal variation of the section would look like:&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;img src="http://www.gwotricks.com/2009/04/informalv.png" /&gt;&lt;/center&gt;&lt;br /&gt;This is a single section with multiple parts to it. Now, how does one use these multiple parts in the actual web page? Here is what the letter part of our pet food web site would look like:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;div class="mycode"&gt;&lt;span class="code_bold"&gt;&amp;lt;p&gt;&amp;lt;script&gt;write_frag('Tone', 1)&amp;lt;/script&gt;&lt;b&gt;Hello&lt;/b&gt;&amp;lt;/noscript&gt;&lt;/span&gt;,&lt;br /&gt;&amp;lt;p&gt;&lt;br /&gt;We're so sure your pet will flip out over this food, we&lt;br /&gt;offer a double your money back guarantee! If your pet&lt;br /&gt;is not satisfied in 30 days of purchase, just return the&lt;br /&gt;unused portion of the food and a notorized letter from&lt;br /&gt;your pet explaining why the food was less than perfect.&lt;br /&gt;&amp;lt;p&gt;&lt;br /&gt;&lt;span class="code_bold"&gt;&amp;lt;script&gt;write_frag('Tone', 2)&amp;lt;/script&gt;&lt;b&gt;Thanks&lt;/b&gt;&amp;lt;/noscript&gt;&lt;/span&gt;,&amp;lt;br&gt;&lt;br /&gt;The Pet Food Company&lt;/div&gt;&lt;/pre&gt;I've highlighted the two section fragments. They are very similar to the standard tags one would use, but instead of calling the &lt;b&gt;utmx_section&lt;/b&gt; function, they call a function called &lt;b&gt;write_frag&lt;/b&gt;. Also notice that the default version of the section fragments are encoded in the page, surrounded by the function call and a &lt;b&gt;&amp;lt;/noscript&gt;&lt;/b&gt; tag - just like standard section tagging.&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Now, the definition of the &lt;b&gt;write_frag&lt;/b&gt; function:&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;div class="mycode"&gt;&amp;lt;!-- utmx section name="Tone" --&gt;&lt;br /&gt;&amp;lt;script&gt;&lt;br /&gt;function write_frag(section, frag_num) {&lt;br /&gt;var content = utmx('variation_content', section);&lt;br /&gt;if (content) {&lt;br /&gt;var token = '%%Frag ' + frag_num + '%%';&lt;br /&gt;var start = content.indexOf(token) + token.length;&lt;br /&gt;var finish = content.indexOf('%%', start);&lt;br /&gt;document.write(content.substring(start, finish));&lt;br /&gt;document.write('&amp;lt;no' + 'script&gt;');&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&amp;lt;/script&gt;&lt;/div&gt;&lt;/pre&gt;The first line of this block of HTML is a special comment which declares the presence of the Tone section to GWO. GWO normally detects the section of a multi-variate experiment by looking for the standard section tags. But, because those are not present, this comment is an alternative way of declaring the section.&lt;br /&gt;&lt;p&gt;First, the write_frag function uses functionality that is defined only after the Control Script has executed on the page.  The write_frag function takes two arguments: a section name and a fragment number. What the function does is acquire the value of the the section's variation as it was entered into GWO:&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;div class="mycode"&gt;var content = utmx('variation_content', section);&lt;/div&gt;&lt;/pre&gt;This call's the &lt;b&gt;utmx&lt;/b&gt; function which is &lt;a href="http://www.gwotricks.com/2009/03/advanced-test-page-functionality.html"&gt;detailed in another article&lt;/a&gt;. This call returns one of the %%'ed variations defined for the specified section which was chosen by GWO for this visitor to see. If an alternative variation is not returned, then the function does nothing else, and the default content is displayed. However, if an alternative variation is returned, then the function searches that variation for a block of text surrounded by the special %% tokens. The start token takes the form &lt;span class="code_bold"&gt;%%Frag #%%&lt;/span&gt; where # is replaced with the number of the fragment. In this example, there are two fragments, but you could have as many as you want.&lt;br /&gt;&lt;p&gt;Then, after isolating the value of the fragment, it &lt;b&gt;document.write&lt;/b&gt;'s this along with a &lt;b&gt;&amp;lt;/noscript&gt;&lt;/b&gt; tag. This is exactly what the &lt;b&gt;utmx_section&lt;/b&gt; does for you in the standard version of section tags. This causes the browser's parser to encounter and display the fragment's value while removing the original's value.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Thus, with this technique, you can define sections which need not be contiguous. Please note that although this example shows how you can have a fragmented section influence a single page, the technique works just as well across multiple pages. Be sure to include the Control Script at the top of each page which contains a section or a fragment of a section.&lt;span style="FONT-WEIGHT: bold"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;I have a &lt;a href="http://www.gwotricks.com/fragmented/test.htm"&gt;web page illustrating this very technique&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8794092920201977674-6997587915231359211?l=www.gwotricks.com%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/8794092920201977674/6997587915231359211/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8794092920201977674&amp;postID=6997587915231359211' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8794092920201977674/posts/default/6997587915231359211'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8794092920201977674/posts/default/6997587915231359211'/><link rel='alternate' type='text/html' href='http://www.gwotricks.com/2009/04/fragmented-sections.html' title='Test non-contiguous pieces of your page with Fragmented Sections'/><author><name>Eric Vasilik</name><uri>http://www.blogger.com/profile/09622601499428032516</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09933651237686075846'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8794092920201977674.post-2033924859417468606</id><published>2009-03-17T23:06:00.000-07:00</published><updated>2009-03-22T10:17:06.909-07:00</updated><title type='text'>Advanced Test Page Functionality</title><content type='html'>&lt;p&gt;Recently, I added functionality to pages which contain the Control Script (these are usually test pages).  This new functionality allows you to obtain more information about the variations and combination chosen for the visitor to a experiment, allowing you more flexibility in developing customized tests.  I will elaborate on testing techniques which use these features in other articles.  In this article, I want to simply document the new functionality in detail.&lt;br /&gt;&lt;/p&gt;&lt;h3&gt;The utmx function&lt;/h3&gt;&lt;br /&gt;All the new functionality are accessed via the &lt;b&gt;utmx&lt;/b&gt; function which is defined as a consequence of including the Control Script on a page.  The utmx function is designed to be the single entry point for most current and all future functionality provided to test pages.  Its signature is:&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;utmx( feature, arg1, arg2, ... argn )&lt;/div&gt;&lt;br /&gt;The first argument is a string which describes the desired feature requested.  The second, third, etc, arguments are dependent on the requested feature.&lt;br /&gt;&lt;p&gt;The value that the utmx function returns is dependent on the requested functionality.  It may be a string, a number or other value.  However, no matter what feature is requested, the utmx function may return &lt;span style="font-weight: bold;"&gt;undefined&lt;/span&gt;.  The undefined return value may indicate that the utmx function was not redefined by the Control Script, and that any GWO related functionality on the page should show default (original) content or take default behavior.  To illustrate this point, consider what the beginning of the Control Script looks like:&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;div class="mycode"&gt;&amp;lt;script&gt;&lt;br /&gt;function utmx_section(){}&lt;span class="code_bold"&gt;function utmx(){}&lt;/span&gt;&lt;br /&gt;(function(){var k='3923492669',d=document,l=d.location,c=d.cookie;function f(n){&lt;br /&gt;.....&lt;/div&gt;&lt;/pre&gt;Notice that the utmx function is initially defined to have an empty body.  When a function like this is called in JavaScript, the return value will be undefined.  If, for whatever reason, the Control Script is unable to load siteopt.js, which redefines the utmx function, this original definition will remain and return undefined for anyone who calls it.  In order to have pages not break under these circumstances, it is important to check the return from utmx for undefined and take the appropriate actions.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Variation Information&lt;/h3&gt;&lt;br /&gt;The following two features allow you to obtain information about what variation was chosen for a given section:&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;utmx( "variation_number", section_name )&lt;/div&gt;&lt;br /&gt;and,&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;utmx( "variation_content", section_name )&lt;/div&gt;&lt;br /&gt;In each case, the section name is the name (a string) of the section for which you want the information.  This is the same value you would pass to the &lt;span style="font-weight: bold;"&gt;utmx_section&lt;/span&gt; function for a multi-variate experiment.  In the case of an A/B experiment, GWO creates a single section called &lt;span style="font-weight: bold;"&gt;"A/B"&lt;/span&gt; which can be used here as well.&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-weight: bold;"&gt;"variation_number"&lt;/span&gt; feature returns either undefined or an integer number between 0 and N-1 where N is the number of variations defined for the given section, including the original.  If 0 or undefined is returned, this indicates that the original content or behavior for the given section was chosen for this visitor. Values 1 through N-1 indicate that a non-original alternative for the given section was chosen for this visitor.  In this case, the appropriate alternative action should take place.&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-weight: bold;"&gt;"variation_content"&lt;/span&gt; feature returns either undefined or a string.  If undefined is returned, this indicates that the original content or behavior for the given section was chosen for this visitor.  Otherwise, a string is returned, indicating that a non-original alternative for the given section was chosen for this visitor.  The value of this string is exactly what was entered in the GWO user interface as the value of the variation chosen for the visitor.  In the case of an A/B experiment, the value returned is the alternative URL entered in GWO user interface, exactly as it was entered.&lt;br /&gt;&lt;br /&gt;Both of these features can indicate non-original alternatives for the given section for both "preview" and "live" page requests and should be used to alter the visuals or behavior of the page.  A "live" request is a test page viewed by a visitor while the test is running, as opposed to a "preview" request which is one performed by the GWO preview window.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Combination Information&lt;/h3&gt;&lt;br /&gt;The following two features allow you to obtain information about what combination was chosen for a "live" visitor.  Note that under "preview" requests, no combination information is available, undefined will be returned.  These features apply only to "live" requests.  Because of this, these features should not be used for altering the appearance or behavior of a test page.  They can only be used to indicate what combination was chosen for a visitor to a running experiment.&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;utmx( "combination" )&lt;/div&gt;&lt;br /&gt;and,&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;utmx( "combination_string" )&lt;/div&gt;&lt;br /&gt;The &lt;span style="font-weight: bold;"&gt;"combination"&lt;/span&gt; feature returns either undefined or an integer between 0 and M-1 where M is the total number of combinations defined for the experiment, including the original.  If undefined is returned, this indicates that this test page request was not a live request.  If 0 is returned, this indicates that the original combination was chosen for the visitor.  Otherwise, 1 through M-1 indicate that a non-original alternative was chosen for the visitor.  Note that M is the product of the variation sizes of all the sections defined for the experiment.  So, if you have an experiment with two sections, say, headline and image, and the headline has 3 alternatives and the image has 4 alternatives (each including the original), then M will be 12.&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-weight: bold;"&gt;"combination_string"&lt;/span&gt; feature has similar semantics as the "combination" feature.   It returns undefined under the same conditions.  However, the return value is a string with the variation numbers for each section separated by dashes.  For example a 3 section multi-variate experiment may return  &lt;span style="font-weight: bold;"&gt;"3-0-2"&lt;/span&gt; where 3 is the variation number for the first section, 0 for the second and 2 for the third.  In this example, &lt;span style="font-weight: bold;"&gt;"0-0-0"&lt;/span&gt; would indicate that the original combination was chosen for the visitor.  Again, undefined indicates that this was not a "live" request.&lt;br /&gt;&lt;br /&gt;For A/B experiments, the combination features behave like a multivariate experiment where there is only one variable.&lt;br /&gt;&lt;br /&gt;An example of using the combination information can be found in this article: &lt;a href="http://www.gwotricks.com/2009/02/poor-mans-gwoanalytics-integration.html"&gt;Poor Man's GWO/Analytics Integration&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Declaring Multivariate Sections&lt;/h3&gt;&lt;br /&gt;When using the above functionality for implementing tests, you will probably no longer use the standard multi-variate section script.  For example:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;div class=mycode&gt;&amp;lt;script&gt;utmx_section("Button")&amp;lt;script&gt;&lt;br /&gt;&amp;lt;input type=button" value="Click Me"&gt;&lt;br /&gt;&amp;lt;/noscript&gt;&lt;/div&gt;&lt;/pre&gt;The standard section script does two things.  First, it declares the section named by the argument to the utmx_section function (Button, in this case).  Secondly, it implements the actual replacement of the default content should a visitor been chosen to see an alternative variation.&lt;br /&gt;&lt;br /&gt;When implementing the more advanced techniques for experiments, you may frequently no longer use the utmx_section function.  However, you will still need to declare a section so that GWO will know the schema of your experiment.  To declare a section without impacting your test page, you can use a special HTML comment.  For example:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;div class=mycode&gt;&amp;lt;!-- utmx section name="Section1" --&amp;gt;&lt;br /&gt;&amp;lt;!-- utmx section name="Section2" --&amp;gt;&lt;/div&gt;&lt;/pre&gt;Declares two sections, but otherwise, has no impact on the page in which it is present (because they are comments).  This way, when you validate your test page in the GWO UI, GWO will see the two sections you intend to declare.  Then, the implementation of those sections on your page is under your, separate, control.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8794092920201977674-2033924859417468606?l=www.gwotricks.com%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/8794092920201977674/2033924859417468606/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8794092920201977674&amp;postID=2033924859417468606' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8794092920201977674/posts/default/2033924859417468606'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8794092920201977674/posts/default/2033924859417468606'/><link rel='alternate' type='text/html' href='http://www.gwotricks.com/2009/03/advanced-test-page-functionality.html' title='Advanced Test Page Functionality'/><author><name>Eric Vasilik</name><uri>http://www.blogger.com/profile/09622601499428032516</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09933651237686075846'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8794092920201977674.post-1737093238369096428</id><published>2009-02-05T12:45:00.000-08:00</published><updated>2009-03-22T13:11:03.637-07:00</updated><title type='text'>Advanced A/B Experiments</title><content type='html'>&lt;p&gt;&lt;br /&gt;GWO provides for an A/B style of testing "out of the box". However, sometimes you may find it does not quite suit your needs, or, you may need more control over the URL to which visitors get redirected.  This article describes how to perform an A/B test where you have much more control over how the redirection to the alternative pages takes place.&lt;br /&gt;&lt;br /&gt;The following is a technique for performing an A/B test such that you have an opportunity to dynamically participate in the construction of the alternative URL's.&lt;/p&gt;&lt;p&gt;First, instead of creating an A/B experiment, create a Multi-Variate experiment. Place the control script at the top of your test (A) page. Place the test page tracking script at the bottom of your test page and alternate pages (B, C, etc). Place the goal tracking script at the bottom of your goal page.&lt;br /&gt;&lt;br /&gt;Now, instead of introducing the multi-variate sections scripts, place the following somewhere in your test page (I recommend it go near the control script):&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="mycode"&gt;&amp;lt;!-- utmx section name="page-url" --&amp;gt;&lt;/div&gt;&lt;br /&gt;This HTML comment is very much like a section script in that it declares a section named "page-url", but does not modify the page or the user's experience at all.&lt;br /&gt;&lt;br /&gt;Now, you can validate the test and goal pages and move on to specifying the alternate URLs which you want to test. Enter these into the GWO UI as the content of variations for the page-url section.  Here I've specified a simple relative URL, but you can specify a complete URL if you want:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;img src="http://www.gwotricks.com/2009/02/ab-step3.png" border="1" /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Before launching or previewing your experiment, place the following script &lt;span style="font-weight: bold;"&gt;immediately&lt;/span&gt; after the control script on your test (A) page:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;div class="mycode"&gt;&amp;lt;script&gt;&lt;br /&gt;function filter(v) {&lt;br /&gt;var b = utmx('variation_content', 'page-url');&lt;br /&gt;var u = v[0].contents;&lt;br /&gt;if (b &amp;amp;&amp;amp; u.substr(0,7) == 'http://' &amp;amp;&amp;amp; b.substr(0, 7) != 'http://') {&lt;br /&gt;u = u.substr(7);&lt;br /&gt;}&lt;br /&gt;return u;&lt;br /&gt;}&lt;br /&gt;utmx('url', 'page-url', 0, filter);&lt;br /&gt;&amp;lt;/script&gt;&lt;/div&gt;&lt;/pre&gt;At this point, you can preview and launch the experiment.  It will behave just like any other A/B experiment.&lt;br /&gt;&lt;br /&gt;You can see an example of this in action here as follows. &lt;blockquote&gt;&lt;a href="http://www.gwotricks.com/abadvanced/a-page.htm#utmxid=EAAAAPTIJhUpg_eC3EXSY5j6vDk;utmxpreview=0;utmxreload=1"&gt;Test (A) Page (inactive)&lt;/a&gt;&lt;/blockquote&gt;Note that that URL will take you to the A page without enrolling you in the experiment. In order to experience a possible redirect, remove the content after the # in the link's URL: &lt;blockquote&gt;&lt;a href="http://www.gwotricks.com/abadvanced/a-page.htm"&gt;Test (A) Page (active)&lt;/a&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;h3&gt;The Filter Function&lt;/h3&gt;&lt;br /&gt;This script above will perform the redirection to alternative pages, should GWO decide that a given visitor is not to see the A page. Let's look at a bit more closely.&lt;br /&gt;&lt;pre&gt;&lt;div class="mycode"&gt;&amp;lt;script&gt;&lt;br /&gt;function filter(v) {&lt;br /&gt;...&lt;br /&gt;}&lt;br /&gt;utmx('url', 'page-url', 0, filter);&lt;br /&gt;&amp;lt;/script&gt;&lt;/div&gt;&lt;/pre&gt;&lt;br /&gt;The &lt;span style="font-weight: bold;"&gt;utmx&lt;/span&gt; function is defined by the control script. It is the main entry point for a variety of GWO functionality available in test pages. In this case, the first argument, 'url' tells the function that it should treat this experiment as an A/B experiment and perform a redirect if necessary. The second argument, 'page-url', is the name of the section which defines the alternative URL's. The third argument is a positional indicator and should be set to zero in this case.  Otherwise, I will not describe it here.&lt;br /&gt;&lt;br /&gt;The fourth argument is a filter function which you define and is called just before redirection takes place. It takes, as an argument, an object containing the redirection URL computed by the utmx function and returns the actual URL to which the user will be redirected. It is your opportunity to get involved in the form of the URL the visitor is redirected.&lt;br /&gt;&lt;br /&gt;Before calling the filter function, the utmx function does a number of things to the target URL. First, it merges all query parameters of the current URL (document.location) with the query parameters of the target URL. This allows an alternate page to have the same information the A page has. For example, you might encode product ID's as a query param:&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;http://www.mystore.com?product=slinky&lt;/div&gt;&lt;br /&gt;You might enter:&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;http://www.mystore.com/b-page.htm&lt;/div&gt;&lt;br /&gt;As the alternative B-page URL for your experiment. Because you are testing all your product pages, you can only specify the B-page URL, sans the product. GWO will redirect to:&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;http://www.mystore.com/b-page.htm?product=slinky&lt;/div&gt;&lt;br /&gt;Which allows your B-page to know which product is being queried and present that product in the context of the B-page.&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-weight: bold;"&gt;utmx('url', ...)&lt;/span&gt; function also looks at the URL and adds http:// to it if it does not already have it. Many times, this is fine, if you don't specify the protocol. For example:&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;www.mystore.com/b-page.htm&lt;/div&gt;&lt;br /&gt;But it can sometimes get in the way. For example, you might want to specify (as I do in my example above), a simple, relative URL for the alternate pages:&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;b-page.htm&lt;/div&gt;&lt;br /&gt;The the code in the custom script above will strip this away as needed:&lt;br /&gt;&lt;pre&gt;&lt;div class="mycode"&gt;var b = utmx('variation_content', 'page-url');&lt;br /&gt;var u = v[0].contents;&lt;br /&gt;if (b &amp;amp;&amp;amp; u.substr(0,7) == 'http://' &amp;amp;&amp;amp; b.substr(0, 7) != 'http://') {&lt;br /&gt;u = u.substr(7);&lt;br /&gt;}&lt;br /&gt;return u;&lt;/div&gt;&lt;/pre&gt;&lt;br /&gt;If the "raw" version of the alternative in the variable 'b' does not begin with http:// but utmx's version does, then it will be stripped away.  Finally, the URL in the variable &lt;span style="font-weight: bold;"&gt;u&lt;/span&gt; is returned where GWO will perform a redirection to it.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;URL Customization&lt;/h3&gt;&lt;br /&gt;The filter function allows you to inspect and modify the redirection URL at will.  To demonstrate this further, consider my example above where the product ID is a query parameter:&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;http://www.mystore.com?product=slinky&lt;/div&gt;&lt;br /&gt;But, what if my site encodes the product in the path of the URL?  Like so:&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;http://www.mystore.com/slinky/a-page.html&lt;/div&gt;&lt;br /&gt;And, I want to test an alternative page, like so?&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;http://www.mystore.com/slinky/b-page.html&lt;/div&gt;&lt;br /&gt;You'd might enter the alternative URL in GWO as:&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;http://www.mystore.com/slinky/b-page.html&lt;/div&gt;&lt;br /&gt;But, because your test page will be called for more than one product, like:&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;http://www.mystore.com/tofu/a-page.html&lt;/div&gt;&lt;br /&gt;You can't enter that URL, otherwise all users will see only the tofu product, regardless of which product they may have clicked on.  Or, you might enter:&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;http://www.mystore.com/b-page.html&lt;/div&gt;&lt;br /&gt;But, no product is specified here, and your web server might produce an error page.&lt;br /&gt;&lt;br /&gt;What you need to do in cases like this is write some custom JavaScript which builds the correct URL.  So, building off the last example, consider the following example.  Let's say the the following URLS are two of among many products:&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;http://www.mystore.com/slinky/a-page.htm&lt;br /&gt;http://www.mystore.com/tofu/a-page.htm&lt;/div&gt;&lt;br /&gt;And you specify an alternative URL like so:&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;http://www.mystore.com/PRODUCT/b-page.htm&lt;/div&gt;&lt;br /&gt;The idea is while computing the URL to which a redirection will take place, inspect the current URL (document.location.href) for the name of the product, and replace the word PRODUCT with the name of the current product in the a-page.  Like so:&lt;br /&gt;&lt;br /&gt;&lt;div class=mycode&gt;&lt;pre&gt;&amp;lt;script&gt;&lt;br /&gt;var b = utmx('variation_content', 'page-url');&lt;br /&gt;function filter(v) {&lt;br /&gt;  var u = v[0].contents;&lt;br /&gt;  if (b &amp;amp;&amp;amp; u.substr(0,7) == 'http://' &amp;amp;&amp;amp; b.substr(0, 7) != 'http://') {&lt;br /&gt;    u = u.substr(7);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;&lt;span class=code_bold&gt;  var l = document.location.href;&lt;br /&gt;  var prefix = 'mystore.com/';&lt;br /&gt;  var i = l.indexOf(prefix);&lt;br /&gt;  var j = l.indexOf('/', i + prefix.length);&lt;br /&gt;  u = u.replace('PRODUCT', l.substring(i + prefix.length, j));&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;  return u;&lt;br /&gt;}&lt;br /&gt;utmx('url', 'page-url', 0, filter);&lt;br /&gt;&amp;lt;/script&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;This is very much like the first example above, but instead of simply returning the URL, we get the current product name and use it to replace the place-holder token, "PRODUCT" which is present in all alternative URL's.  This allows us to redirect to the proper alternative URL, while preserving the current product the visitor is interested in.&lt;br /&gt;&lt;br /&gt;You can see this in action here:&lt;br /&gt;&lt;blockquote&gt;&lt;a href="http://www.gwotricks.com/abadvanced/slinky/b-page.htm"&gt;http://www.gwotricks.com/abadvanced/slinky/b-page.htm&lt;/a&gt;&lt;/blockquote&gt;&lt;br /&gt;Happy redirecting!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8794092920201977674-1737093238369096428?l=www.gwotricks.com%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/8794092920201977674/1737093238369096428/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8794092920201977674&amp;postID=1737093238369096428' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8794092920201977674/posts/default/1737093238369096428'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8794092920201977674/posts/default/1737093238369096428'/><link rel='alternate' type='text/html' href='http://www.gwotricks.com/2009/02/advanced-ab-experiments.html' title='Advanced A/B Experiments'/><author><name>Eric Vasilik</name><uri>http://www.blogger.com/profile/09622601499428032516</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09933651237686075846'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8794092920201977674.post-2873986619346320728</id><published>2009-02-03T15:00:00.000-08:00</published><updated>2009-03-18T00:54:34.469-07:00</updated><title type='text'>Where does the Control Script belong?</title><content type='html'>&lt;p&gt;I frequently see test pages in which the control script is not placed in a good location.  In this article, I want to talk about the things to consider when placing the control script into your test pages.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;Latency&lt;/h3&gt;&lt;br /&gt;The presence of the control script in your page will introduce latency into the total load time of the page.  When the control script executes, it generates a request for a Google resource called siteopt.js. The latency is attributed to the time it takes for siteopt.js to load.  To demonstrate this, with Firefox, you can load siteopt.js in the presence of the &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/1843"&gt;Firebug add-on&lt;/a&gt; that can measure the amount of time that it takes the page to fetch various resources.  For me, inside the Google corporate network, it takes on average about 20 milliseconds to load siteopt.js:&lt;p&gt;&lt;/p&gt;&lt;center&gt;&lt;img src="http://www.gwotricks.com/2009/02/corp-latency.png" /&gt;&lt;/center&gt;&lt;p&gt;When I do the same thing from my home, it takes a little more time, about 36 milliseconds (I use a microwave based ISP, which adds a little bit of latency to everything):&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;center&gt;&lt;img src="http://www.gwotricks.com/2009/02/home-latency.png" /&gt;&lt;/center&gt;&lt;p&gt;In order to minimize this latency, Google distributes the servers that respond to siteopt.js requests all over the globe.  This way, visitors from &lt;a href="http://maps.google.com/maps?f=q&amp;amp;source=s_q&amp;amp;hl=en&amp;amp;q=Mongolia&amp;amp;sll=75.140778,148.710938&amp;amp;sspn=114.90857,360&amp;amp;ie=UTF8&amp;amp;cd=1&amp;amp;geocode=FaAQywIdAJMwBg&amp;amp;split=0&amp;amp;t=h&amp;amp;ll=46.920255,104.326172&amp;amp;spn=95.508987,223.59375&amp;amp;z=3"&gt;Mongolia&lt;/a&gt; to your test page don't have to load siteopt.js from a faraway server in the United States, they will probably get siteopt.js from a server in Asia, or Northern Europe.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Redirection&lt;/h3&gt;&lt;br /&gt;If you are running an A/B experiment, the control script may cause a redirection to happen if Google decides that this particular visitor should see a page other than the A page.  This means that all the processing that the browser is doing when the redirect takes place will be aborted when the new page is loaded.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Other Resources&lt;/h3&gt;&lt;br /&gt;Given these aspects of the control script, it is very important that the control script appear &lt;span style="font-weight: bold;"&gt;before&lt;/span&gt; any references to external resources.  These include CSS, script, image, objects, and the like.  The reason for this is that if the control script decides to perform a redirect, all the time and work involved in loading these resources will be wasted and, most likely, performed again in the target of the redirect.  This leads to increasing the total latency that the visitor experiences.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Displayable Content&lt;/h3&gt;&lt;br /&gt;Because the control script loads alternative content used in the display of the page, it needs to appear before the points in the page that potentially use this alternative content.  Additionally, it is very important that the control script appear before &lt;span style="font-weight: bold;"&gt;any&lt;/span&gt; content in the page that is displayed to the user.&lt;br /&gt;&lt;br /&gt;The reason for this is, again, latency.  If the control script were to appear after, say, the first paragraph of the page, the user would see that paragraph, experience a very brief latency, and then the rest of the page would display.  However, if the control script were to appear before this paragraph, then the window remains blank during the small latency, and then the page would render as a whole.  This is a better experience for the user.&lt;br /&gt;&lt;br /&gt;Also, a browser may spend less time laying out the page because there is no interruption of the display of the page.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Document Type Declaration&lt;/h3&gt;&lt;br /&gt;Many pages have a document type declaration.  It may look something like this:&lt;br /&gt;&lt;pre&gt;&lt;div class="mycode"&gt;&amp;lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"&gt;&lt;/div&gt;&lt;/pre&gt;Browsers will change the way they parse an HTML file based on this declaration.  In order to determine the type of a page, browsers will "sniff" for this declaration at the very beginning of the page.  If they find a well formed declaration, then the parser for that document type will be instantiated.&lt;br /&gt;&lt;br /&gt;It is &lt;span style="font-weight: bold;"&gt;very&lt;/span&gt; important that the control script appear after any document type declaration.  The reason for this is that browsers will only look so far into an HTML document when sniffing for these declarations.  The presence of the control script before the declaration may cause the browser to not find the declaration and to choose the wrong parser.  This can have &lt;span style="font-weight: bold;"&gt;devastating&lt;/span&gt; effects on a page, potentially rendering it unusable.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;br /&gt;So, in a well formed HTML document, the control script should be:&lt;ul&gt;&lt;li&gt;After any document type declaration&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Before any other resources (CSS, scripts, etc)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Before any displayable content (text, tables, etc)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;In a well formed document, these restrictions are usually accommodated by placing the control script as the &lt;span style="font-weight: bold;"&gt;very&lt;/span&gt; first element of the head element, just after the beginning &amp;lt;HEAD&gt; tag.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8794092920201977674-2873986619346320728?l=www.gwotricks.com%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/8794092920201977674/2873986619346320728/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8794092920201977674&amp;postID=2873986619346320728' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8794092920201977674/posts/default/2873986619346320728'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8794092920201977674/posts/default/2873986619346320728'/><link rel='alternate' type='text/html' href='http://www.gwotricks.com/2009/02/where-does-control-script-belong.html' title='Where does the Control Script belong?'/><author><name>Eric Vasilik</name><uri>http://www.blogger.com/profile/09622601499428032516</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09933651237686075846'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8794092920201977674.post-5554222549874455197</id><published>2009-02-01T00:06:00.001-08:00</published><updated>2009-11-16T00:08:31.170-08:00</updated><title type='text'>Poor Man's GWO/Analytics Integration</title><content type='html'>&lt;p&gt;A while back, &lt;a href="http://www.roirevolution.com/"&gt;ROI Revolution&lt;/a&gt; (a Google Website Optimizer Authorized Consultant) came up with a technique for importing GWO information into GA (Google Analytics).  This way, you can see how different variations of a web page/site will affect the various numbers that GA measures.&lt;br /&gt;&lt;br /&gt;The original technique relied on munging through the __utmx cookie that the control script sets.  I improved upon this by describing a technique which uses some new functionality I incorporated into siteopt.js.  Their most recent description of this technique is &lt;a href="http://www.roirevolution.com/blog/2008/11/google_website_optimizer_renews.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I've been giving some thought to this technique and wanted to 1) Improve the technique a bit, and 2) Suggest an alternative which has some significant advantages.&lt;br /&gt;&lt;br /&gt;First, an look at my script for the ROI technique.  The script I suggested is (note, all these scripts assume that ga.js and the control script have already been included on the page):&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;div class="mycode"&gt;&amp;lt;script type="text/javascript"&gt;&lt;br /&gt;if (utmx('combination') != undefined) {&lt;br /&gt;var l = document.location, s = l.search;&lt;br /&gt;s = s + (s.length ? '&amp;amp;' : '?') + 'combination=' + utmx('combination');&lt;br /&gt;var pageTracker = _gat._getTracker("UA-XXXXXX-Y");&lt;br /&gt;pageTracker._trackPageview(l.pathname + s);&lt;br /&gt;}&lt;br /&gt;&amp;lt;/script&gt;&lt;/div&gt;&lt;/pre&gt;&lt;br /&gt;This suffers from two things.  First, global variables are introduced into the namespace of the page and, second, there is no specification of which experiment is annotating the hits.  So, consider the following, modified, script:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;div class="mycode"&gt;&amp;lt;script type="text/javascript"&gt;&lt;br /&gt;(function(){try {&lt;br /&gt;if (utmx('combination') != undefined) {&lt;br /&gt;var l = document.location, s = l.search;&lt;br /&gt;s = s + (s.length ? '&amp;amp;' : '?') + 'combination=' + utmx('combination');&lt;br /&gt;s += '&amp;amp;experiment=MyExperiment';&lt;br /&gt;var pageTracker = _gat._getTracker("UA-XXXXXX-Y");&lt;br /&gt;pageTracker._trackPageview(l.pathname + s);&lt;br /&gt;}&lt;br /&gt;}catch(err){}})();&lt;br /&gt;&amp;lt;/script&gt;&lt;/div&gt;&lt;/pre&gt;&lt;br /&gt;Here I've enclosed the script in an anonymous function and a block to catch exceptions (should ga.js fail to load), and also added a query param describing the experiment being tested to disambiguate one experiment from another.&lt;br /&gt;&lt;br /&gt;With this technique, you can go into your content report in GA and see how many visitors assigned to the various experiment variations actually end up visiting pages on your site.&lt;br /&gt;&lt;br /&gt;This technique requires you to modify the GA tracking script on each page of your site which you want to track against an experiment.  If you've already instrumented your whole site with GA tags, it might be cumbersome to edit them all, especially when you'll need to modify them again when you end and experiment, or start a new one.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Experimenting on the entire Site&lt;/h3&gt;&lt;br /&gt;The answer I've come up with to deal with these issues is to integrate GWO experiment information a different way.  Instead of modifying each page URL with the experiment information, you can set the GA user variable with experiment information (assuming you are not already using the variable for other purposes).  Consider the following script:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;div class="mycode"&gt;&amp;lt;script type="text/javascript"&gt;&lt;br /&gt;try {&lt;br /&gt;var pageTracker = _gat._getTracker("UA-XXXXXX-Y");&lt;br /&gt;pageTracker._setVar("MyExperiment-" + utmx('combination'));&lt;br /&gt;} catch(err) {}&lt;br /&gt;&amp;lt;/script&gt;&lt;/div&gt;&lt;/pre&gt;&lt;br /&gt;First note that this script does not call _trackPageView.  Its job is not to track anything, but to set up the user variable to contain information about an experiment.   This variable is stored in the __utmv cookie, and every subsequent call to _trackPageView in a tracking script will communicate the value of this cookie to Google servers and annotate the page view with the value in the cookie.&lt;br /&gt;&lt;br /&gt;This script needs to placed in a particular place in your pages.  First, it must only be located in GWO test pages which have already executed the control script.  The script uses the function &lt;b&gt;utmx&lt;/b&gt;, which is defined by siteopt.js, which is obtained through the control script.  Next, this script needs to be executed before any calls to &lt;b&gt;_trackPageView&lt;/b&gt; in any other GA tracking scripts.  It also needs to be after the inclusion of ga.js.&lt;br /&gt;&lt;br /&gt;I recommend that you place this script after the ga.js inclusion script and before the GA tracking script in the following manner:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;div class="mycode"&gt;&amp;lt;script type="text/javascript"&gt;&lt;br /&gt;var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");&lt;br /&gt;document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));&lt;br /&gt;&amp;lt;/script&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&amp;lt;script type="text/javascript"&gt;&lt;br /&gt;try {&lt;br /&gt;var pageTracker = _gat._getTracker("UA-XXXXXX-Y");&lt;br /&gt;pageTracker._setVar("MyExperiment-" + utmx('combination'));&lt;br /&gt;} catch(err) {}&amp;lt;/script&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&amp;lt;script type="text/javascript"&gt;&lt;br /&gt;try {&lt;br /&gt;var pageTracker = _gat._getTracker("UA-XXXXXX-Y");&lt;br /&gt;pageTracker._trackPageview();&lt;br /&gt;} catch(err) {}&amp;lt;/script&gt;&lt;/p&gt;&lt;/div&gt;&lt;/pre&gt;&lt;br /&gt;This way, the variable gets set before the tracking script which will use the variable annotate this page visit.  Furthermore any visits that this visitor makes in the future (for up to an absence of two years) will also be annotated.&lt;br /&gt;&lt;br /&gt;You can see this in action here:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;a href="http://gwotricks.com/gaintegration/testpage.htm"&gt;Test Page&lt;/a&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Special Consideration for A/B Experiments&lt;/h3&gt;&lt;br /&gt;The technique described above works for multi-variate experiments.  That is, experiments which do not use redirection to present different pages to visitors.  If you were to use this technique on GWO A/B experiment, the code which sets the user defined variable would sometimes not get executed because the original page would redirect to an alternate page, skip the setting on the original page for one which does not have the Control Script, and can't use the "utmx" function.&lt;br /&gt;&lt;br /&gt;Now, there are is a way to have the Control Script on A/B alternate pages.  I'll save that technique for another article.  However, there is a way to get the above technique to work A/B (redirection) experiments.  The idea is to set the user defined variable &lt;i&gt;before&lt;/i&gt; the redirection on the original page takes place.  To do this, consider the following A/B Control Script:&lt;pre&gt;&lt;div class="mycode"&gt;&amp;lt;script&gt;&lt;br /&gt;function utmx_section(){}function utmx(){}&lt;br /&gt;(function(){var k='3923492669',d=document,l=d.location,c=d.cookie;function f(n){&lt;br /&gt;if(c){var i=c.indexOf(n+'=');if(i&gt;-1){var j=c.indexOf(';',i);return c.substring(i+n.&lt;br /&gt;length+1,j&amp;lt;0?c.length:j)}}}var x=f('__utmx'),xx=f('__utmxx'),h=l.hash;&lt;br /&gt;d.write('&amp;lt;sc'+'ript src="'+&lt;br /&gt;'http'+(l.protocol=='https:'?'s://ssl':'://www')+'.google-analytics.com'&lt;br /&gt;+'/siteopt.js?v=1&amp;amp;utmxkey='+k+'&amp;mp;utmx='+(x?x:'')+'&amp;amp;utmxx='+(xx?xx:'')+'&amp;amp;utmxtime='&lt;br /&gt;+new Date().valueOf()+(h?'&amp;amp;utmxhash='+escape(h.substr(1)):'')+&lt;br /&gt;'" type="text/javascript" charset="utf-8"&gt;&amp;lt;/sc'+'ript&gt;')})();&lt;br /&gt;&amp;lt;/script&gt;&lt;br /&gt;&amp;lt;script&gt;utmx("url",'A/B');&amp;lt;/script&gt;&lt;/div&gt;&lt;/pre&gt;Notice that this is really two scripts.  The first script is that which, among other things, defines the "utmx" function.  The second, using the "utmx" function, is the one responsible for performing the redirect to an alternative page, should it be required.&lt;br /&gt;&lt;br /&gt;It is &lt;i&gt;between&lt;/i&gt; these two scripts where you will need to include ga.js and set the user defined variable in order for this technique to work for A/B experiments.  So in the A/B case, move that code from just before the tracking script to be between these scripts.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Experiment without GWO reports&lt;/h3&gt;&lt;br /&gt;When you normally set up a GWO experiment, you are asked to place test and goal page tracking scripts on your test page and goal page.  This allows GWO to track when visitors hit your test and goal pages, and render a GWO report.&lt;br /&gt;&lt;br /&gt;If you only plan to look at the GA reports for this experiment, you can forgo placing the GWO tracking scripts.  Instead, you need only place the control script and user defined variable script in any pages which have experiment variations.  In fact, you can place these scripts on pages which do &lt;b&gt;not&lt;/b&gt; have any experiment variations.  The effect of doing this is that visitors to these non-variation pages will have their experiment variations chosen for them before they encounter any test pages.  This means that you will be able to track their activity before they encounter experiment variations.&lt;br /&gt;&lt;br /&gt;This is useful in that, if you do this at every entry point to your site, all tracking events will be tagged with experiment information.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Report Segmentation&lt;/h3&gt;&lt;br /&gt;So, once you get all this set up, how do get experiment segmented reports?  On each report, there is a &lt;span style="font-weight:bold;"&gt;Dimension&lt;/span&gt; dropdown:&lt;br /&gt;&lt;br /&gt;&lt;img style="padding-left:40" src="http://www.gwotricks.com/2009/02/dimension.png" /&gt;&lt;br /&gt;&lt;br /&gt;This will show a report broken down by the values of the user defined variable.  You can use this to get an idea of how individual variations of your site influence this GA stat.&lt;br /&gt;&lt;br /&gt;Note that this is not like a GWO report.  These are just raw numbers and are not analyzed for confidence with respect to which variation is statistically significant.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8794092920201977674-5554222549874455197?l=www.gwotricks.com%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/8794092920201977674/5554222549874455197/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8794092920201977674&amp;postID=5554222549874455197' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8794092920201977674/posts/default/5554222549874455197'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8794092920201977674/posts/default/5554222549874455197'/><link rel='alternate' type='text/html' href='http://www.gwotricks.com/2009/02/poor-mans-gwoanalytics-integration.html' title='Poor Man&apos;s GWO/Analytics Integration'/><author><name>Eric Vasilik</name><uri>http://www.blogger.com/profile/09622601499428032516</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09933651237686075846'/></author><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8794092920201977674.post-1411574946580020690</id><published>2009-01-30T13:48:00.001-08:00</published><updated>2009-04-20T18:24:31.126-07:00</updated><title type='text'>Multiple Goals</title><content type='html'>&lt;p&gt;Today in GWO you can track, for example, when a visitor purchases something &lt;span style="font-weight: bold;"&gt;and/or&lt;/span&gt; signs up for a newsletter. This is done by simply executing the goal tracking script for both of these events. However, some experimenters want to track these kinds of things independently: how do site variations influence purchases independent of sign ups and vice-versa, for the same visitors.&lt;br /&gt;&lt;br /&gt;For the purposes of the description of this technique, I will assume a multi-variate experiment is being used. Later on, I will describe how to adapt the technique to an A/B experiment.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.gwotricks.com/2009/01/exptlist.png" /&gt;&lt;br /&gt;&lt;span style="font-size:-1;"&gt;The experiments I created for my &lt;a href="http://www.gwotricks.com/multiplegoals/testpage.htm"&gt;sample test&lt;/a&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Begin by creating two nearly identical GWO experiments (I recommend giving them the same name, followed by '1' and '2', respectively). The first experiment should be set up normally. Assuming an MVT experiment, put the control script at the top of the test page, the tracking script at the bottom, and the section scripts throughout. Also place the goal tracking script at the bottom of the your first goal page (or wherever you want the first goal to fire).&lt;br /&gt;&lt;br /&gt;You can then validate the first experiment. and continue on to adding the variations for the experiment's various sections. Once done with that, you can progress on to the launch page, but do not launch the experiment at this time.&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Then create the second experiment for the same test page and the second goal page. Do not place the control script for this second experiment in any pages. Do place the test page tracking script from the second experiment just after the test page tracking script for the first experiment. You will not want to modify the section scripts in any way. Do place the second experiment's goal tracking script at the bottom your second goal page (or wherever you want the second goal to fire).&lt;br /&gt;&lt;br /&gt;When you try to validate the second experiment, because the control script is not present on the test page, it will fail. Simply click continue in the validation dialog box, then click the continue button on the install page (which should now be enabled). You will be presented with a confirmation dialog because validation did not complete. You can also upload temporary test and goal pages for the second experiment to get past validation (this will be required for A/B experiments because the A/B experiment wizard does not allow for skipping validation at this time).&lt;br /&gt;&lt;br /&gt;For the second experiment you will need to create the same number of variations for each section as the sections in the first experiment. However, you will not need to fill in any alternative content, just leave the variation content alone for variations in the second experiment, that content will not be used. You should name the variations in the second experiment the same as the first. You should then launch the second experiment. It will not yet have any effect.&lt;br /&gt;&lt;br /&gt;Then, place the following custom script immediately after the control script for the first experiment:&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;div class="mycode"&gt;&amp;lt;script&gt;&lt;br /&gt;(function() {&lt;br /&gt;function set_cookie(name,value,timeout) {&lt;br /&gt;if (_udn &amp;amp;&amp;amp; _udn != "") value += ";domain=" + _udn;&lt;br /&gt;value += ";path=" + _utcp;&lt;br /&gt;if (timeout == 0 &amp;amp;&amp;amp; _utimeout &amp;amp;&amp;amp; _utimeout != "") timeout = _utimeout;&lt;br /&gt;if (timeout &gt; 0) value += ";expires=" + (new Date((new Date).getTime()+timeout*1000)).toGMTString();&lt;br /&gt;document.cookie = name + "=" + value;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function CopyExperiment(src_key, dst_key, dst_id, dst_g, cookie) {&lt;br /&gt;var cs = document.cookie.split(';');&lt;br /&gt;for (var i = 0; i &amp;lt; cs.length; i++) {&lt;br /&gt;  var c = cs[i].split('=');&lt;br /&gt;  var s = c[0];&lt;br /&gt;  while (s.length &gt; 1 &amp;amp;&amp;amp; s[0] == ' ') s = s.substr(1);&lt;br /&gt;  while (s.length &gt; 1 &amp;amp;&amp;amp; s[s.length - 1] == ' ') s = s.substr(0, s.length - 1);&lt;br /&gt;  if (c.length == 2 &amp;amp;&amp;amp; s == cookie) {&lt;br /&gt;    var es = c[1].split('.');&lt;br /&gt;    var d = 0;&lt;br /&gt;    var dv = "";&lt;br /&gt;    for (var j = 1; j &amp;lt; es.length; j++) {&lt;br /&gt;      var ek = es[j].substr(10, 10);&lt;br /&gt;      if (ek == dst_key) {&lt;br /&gt;        d = j;&lt;br /&gt;      } else if (ek == src_key) {&lt;br /&gt;        if (dst_g.length &gt; 0) {&lt;br /&gt;          dv = dst_id + dst_key + ':' + dst_g + es[j].substr(22);&lt;br /&gt;        } else {&lt;br /&gt;          dv = dst_id + dst_key + es[j].substr(20);&lt;br /&gt;        }&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;    if (dv.length &gt; 0) {&lt;br /&gt;      if (d == 0) {&lt;br /&gt;        es.push(dv);&lt;br /&gt;      } else {&lt;br /&gt;        es[d] = dv;&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;    set_cookie(cookie, es.join('.'), 63072000);&lt;br /&gt;    return;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;p&gt;&lt;br /&gt;// Custom variables, adapt them to your own experiments&lt;br /&gt;var src_key = '&lt;span class="code_bold"&gt;3923492669&lt;/span&gt;';&lt;br /&gt;var dst_key = '&lt;span class="code_bold"&gt;4234772301&lt;/span&gt;';&lt;br /&gt;var dst_id = '&lt;span class="code_bold"&gt;0000370338&lt;/span&gt;';&lt;br /&gt;var dst_goal = '&lt;span class="code_bold"&gt;2&lt;/span&gt;';&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;CopyExperiment(src_key, dst_key, dst_id, dst_goal, '__utmx');&lt;br /&gt;CopyExperiment(src_key, dst_key, dst_id, '', '__utmxx');&lt;br /&gt;})();&lt;br /&gt;&amp;lt;/script&gt;&lt;/p&gt;&lt;/div&gt;&lt;/pre&gt;&lt;br /&gt;You can obtain a copy of this script from the source of my &lt;a href="http://www.gwotricks.com/multiplegoals/testpage.htm"&gt;example test page&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;First note the four customizable variables near the end of the script. You will need to modify these to adapt the custom script to your new experiments. The effect of this script will be to copy experiment information from the GWO cookies for the first experiment to that for the second. The first three numbers need to be quoted, zero padded 10 digit numbers. The last is a single quoted digit.&lt;br /&gt;&lt;br /&gt;For the value of &lt;span style="font-weight: bold;"&gt;src_key&lt;/span&gt;, substitute the experiment key for your first experiment. You can find this key near the beginning of the first experiment's control script:&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;&amp;lt;script&gt;&lt;br /&gt;function utmx_section(){}function utmx(){}&lt;br /&gt;(function(){var k='&lt;span class="code_bold"&gt;3923492669&lt;/span&gt;',d=document,l=d.location,c=d.cookie;function f(n){&lt;br /&gt;if(c){var i=c.indexOf(n+'=');if(i&gt;-1){var j=c.indexOf(';',i);return c.substring(i+n.&lt;br /&gt;length+1,j&amp;lt;0?c.length:j)}}}var x=f('__utmx'),xx=f('__utmxx'),h=l.hash;&lt;br /&gt;d.write('&amp;lt;sc'+'ript src="'+&lt;br /&gt;'http'+(l.protocol=='https:'?'s://ssl':'://www')+'.google-analytics.com'&lt;br /&gt;+'/siteopt.js?v=1&amp;amp;utmxkey='+k+'&amp;mp;utmx='+(x?x:'')+'&amp;amp;utmxx='+(xx?xx:'')+'&amp;amp;utmxtime='&lt;br /&gt;+new Date().valueOf()+(h?'&amp;amp;utmxhash='+escape(h.substr(1)):'')+&lt;br /&gt;'" type="text/javascript" charset="utf-8"&gt;&amp;lt;/sc'+'ript&gt;')})();&lt;br /&gt;&amp;lt;/script&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Remember that in the custom script above, this must be enclosed in quotes and be a 0 padded, 10 digit number.&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-weight: bold;"&gt;dst_key&lt;/span&gt; is similar to the src_key; it can be found at the same place in the second experiment's control script.&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-weight: bold;"&gt;dst_id&lt;/span&gt; and &lt;span style="font-weight: bold;"&gt;dst_goal&lt;/span&gt; are a bit more difficult to find. To obtain them, load the following URL into Firefox, or use the &lt;span style="font-style: italic;"&gt;curl&lt;/span&gt; command (other browsers, like IE, will not show you the source of the returned script). Be sure to substitute the 10 digit utmxkey with the experiment key of your second experiment (the value of dst_key).&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;http://www.google-analytics.com/siteopt.js?utmxkey=&lt;span class="code_bold"&gt;4234772301&lt;/span&gt;&amp;amp;utmx=&amp;amp;utmxx=&lt;/div&gt;&lt;br /&gt;This URL will return a chunk of JavaScript which, probably around the third line (which will be rather long), will contain something that looks like:&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;set_cookie('__utmx','&lt;span class="code_bold"&gt;0000370338&lt;/span&gt;4234772301:&lt;span class="code_bold"&gt;2&lt;/span&gt;:0-1',63072000)&lt;/div&gt;&lt;br /&gt;The single digit located between colons is the value you will need for &lt;b&gt;dst_goal&lt;/b&gt;. In this example it is 2. Find this value and substitute it for the one in the custom script. Make sure this is the set_cookie call for __utmx, not __utmxx.&lt;br /&gt;&lt;br /&gt;Then, locate the 20 digit, zero-padded number, just before the number for the dst_goal. The first 10 digits of this number is what you'll use for the &lt;b&gt;dst_id&lt;/b&gt;. Substitute this number for the one in the custom script.&lt;br /&gt;&lt;br /&gt;You can now preview the first experiment to make sure it looks good, and then launch the first experiment. You should now have two new experiments, each of which are running. If you need to pause the multiple-goal experiment, you need only pause the first experiment.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.gwotricks.com/2009/01/cookies.png" /&gt;&lt;br /&gt;&lt;span style="font-size:-1;"&gt;Example of GWO's __utmx cookie created when visiting &lt;a href="http://www.gwotricks.com/multiplegoals/testpage.htm"&gt;sample test page&lt;/a&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;When a visitor loads a test page, after the control script has run and has updated the GWO cookies to contain information about the first experiment (which combination the visitor is to see, most specifically), the custom script will execute and update the GWO cookie to mimic, for the second experiment, the combination chosen for the first experiment. This way, both experiments, on a per visitor basis, will be in sync with each other. However, because the two experiments have different goals, visitors will tracked differently with respect to these goals.&lt;br /&gt;&lt;br /&gt;The report for the first experiment will show you how the first goal converts for all the users of the experiment, while the report for the second experiment will show you how the second goal converts for the exact same set of visitors.&lt;br /&gt;&lt;br /&gt;Note that you will need to perform the preceeding customization for any page which is tested.  That is, anywhere you would have placed the control script, you need to also include the custom script above, and anywhere you would have placed a test page tracking script, you will need to have both test page tracking scripts for both experiments.&lt;br /&gt;&lt;br /&gt;With respect to goal page tracking scripts, these are treated exactly as any normal experiment.  For example, you can trigger the test page tracking script in response to a click event.  There is no need for customization of the goal tracking scripts.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Example Files&lt;/h3&gt;&lt;br /&gt;I have constructed an example using this technique. You should be able to visit the test and goal pages and see your cookies reflect the presence of the two experiments (which are actually running live):&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.gwotricks.com/multiplegoals/testpage.htm"&gt;Test Page&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.gwotricks.com/multiplegoals/goalpage1.htm"&gt;Goal Page 1&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.gwotricks.com/multiplegoals/goalpage2.htm"&gt;Goal Page 2&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Customizing A/B Experiments&lt;/h3&gt;&lt;br /&gt;If you want to use this technique for an A/B experiment, you will perform a very similar setup. The only modification you will need to make is to edit the control script of the first experiment in your test (A) page. At the end of the control script for an A/B experiment, you will find the following script:&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;&amp;lt;script&gt;utmx("url",'A/B');&amp;lt;/script&gt;&lt;/div&gt;&lt;br /&gt;You will need to remove this from the control script and place it to be after the custom script. This script is executed to perform the redirection to alternative pages, and needs to take place after the editing of the GWO cookies for multiple goals.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Reporting&lt;/h3&gt;&lt;br /&gt;I have noticed that the reports for the two experiments can sometimes show a different number of visitors for the same combinations. But I have found that over time the two reports synchronize.&lt;br /&gt;&lt;br /&gt;Because the two experiments have different goals, they will probably not recognize the same winners, or have the same amount of confidence. You will have to choose which combination, on whatever experiment, satisfies you.&lt;br /&gt;&lt;br /&gt;Also, because you are measuring two goals simultaneously, you should wait for a combination for either goal to become a particularly clear winner before acting upon it. The idea behind this is that you are waiting for two events to show significance without controlling for it. One of two events has a better chance of looking significant than one alone, so wait a bit longer for a winner to take a particularly significant lead.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Future Compatibility&lt;/h3&gt;&lt;br /&gt;This technique replies on the fact that, currently, the control script creates and edits GWO cookies (actually, siteopt.js does this, but the control script fetches siteopt.js). I have been considering changing this so that instead of the control script manipulating cookies, the test page tracking script will do this. This probably won't happen for a while, but when it does, you will have to modify this technique slightly.&lt;br /&gt;&lt;br /&gt;How will you know when this may be the case? I will probably modify the control script to have a new version number. Here is the line from the control script which would be modified:&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;+'/siteopt.js?&lt;span class="code_bold"&gt;v=1&lt;/span&gt;&amp;amp;utmxkey='+k+'&amp;amp;utmx='+(x?x:'')+'&amp;amp;utmxx='+(xx?xx:'')+'&amp;amp;utmxtime='&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The new version number will be 2 (or greater), indicating that the control script is different and may no longer be setting cookies. You can verify this by making the above request for &lt;b&gt;siteopt.js&lt;/b&gt; for one of your new, running, experiments. I recommend the second experiment which you launch early. You will want to check to see if it still performs a &lt;b&gt;set_cookie&lt;/b&gt; call. It is also possible that the control script's version number may not change, and siteopt.js will simply not set cookies for new experiments. Thus, you'll just need test to see what the situation is.&lt;br /&gt;&lt;br /&gt;When the control script no longer edits cookies, there may be three ways to continue to use this technique (assuming GWO has not already built in multiple goals):&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Place the custom script to come after the first experiment's test page tracking script, which will have created the GWO cookies. Then, when the second experiment's tracking script is called, the custom script will have edited them properly.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Revert the version of the control script back to the last version which still has it setting cookies.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Instead of the control script editing GWO cookies it will probably edit a the GA global variable to contain the new values to be assigned to the GWO cookies which the tracking script will set. Edit the values in the GA global variable.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;In any case, until this change takes place, I'll not know what the correct workaround will be, so make sure you test this technique before using it. When I do effect the change, I'll try to remember to update this article. Remind me if I've forgotten :-)&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;More than Two Goals&lt;/h3&gt;&lt;br /&gt;This technique should also generalize to more than two goals. Simply create a new experiment for each additional goal and treat it in a similar fashion as the second experiment above.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Stopping, Pruning, Creating Copies and Follow Up Experiments&lt;/h3&gt;&lt;br /&gt;To stop this kind of experiment, simply stop both experiments at the same time. Also, when making copies or creating follow up experiments, simply perform the same operation on both experiments.&lt;br /&gt;&lt;br /&gt;When pruning, one need only prune combos from the first experiment. If you want, you can prune the same combos on the second. In general, performing any operation should be applied to both experiments.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Report Discrepancies&lt;/h3&gt;&lt;br /&gt;In general, the number of impressions that one sees for variations in both experiments should be exactly the same.  However, because the experiments are, essentially, being tracked independently, differences can arise.  There are a variety of reasons for this which are, to a great extent, out of your control.  &lt;br /&gt;&lt;br /&gt;For example, if a visitor to your site closes the window immediately after loading the site, one of the tracking requests might get through, while the other is canceled.  &lt;br /&gt;&lt;br /&gt;However, the discrepancies should either reconcile after a couple of days, or be small.  For example, my example experiments currently read:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.gwotricks.com/2009/01/report.png" /&gt;&lt;br /&gt;&lt;br /&gt;Showing a slight discrepancy.  I would not be too concerned unless it starts to differ by more than, say, 5%.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Interpreting Reports&lt;/h3&gt;&lt;br /&gt;So, what does one do if a variation is a winner in one report and and a loser in another?  Well, that's up to you and how much you value each conversion.  I would recommend running a multiple-goal follow up experiment.  The more metrics you measure, the greater the chance that one of them may be misleading.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8794092920201977674-1411574946580020690?l=www.gwotricks.com%2Fdefault.htm' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.blogger.com/feeds/8794092920201977674/1411574946580020690/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8794092920201977674&amp;postID=1411574946580020690' title='20 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8794092920201977674/posts/default/1411574946580020690'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8794092920201977674/posts/default/1411574946580020690'/><link rel='alternate' type='text/html' href='http://www.gwotricks.com/2009/01/multiple-goals.html' title='Multiple Goals'/><author><name>Eric Vasilik</name><uri>http://www.blogger.com/profile/09622601499428032516</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='09933651237686075846'/></author><thr:total>20</thr:total></entry></feed>
