type:
integration
supports-foxycart-version-from:
0.3.0
supports-foxycart-version-to:
0.6.0
system:
Google Analytics
name:
Ecommerce Tracking for Google Analytics
description:
Tutorial to set up ecommerce tracking for Google Analytics and FoxyCart
tag:
analytics, tutorial, tracking
date:
2010-01-08
version:
FoxyCart v060. Google Analytics as of 2010-01-08

Google Analytics Ecommerce Tracking

Read This First:

NOTE: This page describes Google Analytics integration for FoxyCart v0.6.0 and prior. If you need v0.7.0 instructions please see the Google Analytics Asynchronous for v0.7.0+ docs.

Assumptions

  1. The instructions and code below is current as of FoxyCart v060 and Google Analytics as of 2009-01-08. If you notice things that should be changed please let us know on our forum.
  2. If you've applied any advanced filters to rewrite your request URIs you'll need to take that into account when setting your goal and funnel. If you don't know what that means, you probably don't have to worry about it, but rewriting the request URI can be useful when you're tracking multiple subdomains in one profile.

Other important Google Analytics stuff

  • We strongly recommend setting up a separate Google Analytics profile to test with. It can be tricky, and if you use your primary profile it may dirty up your data.
  • Your products should use the SKU parameter in Google Analytics, which is the code parameter in FoxyCart. If your products do not include a code value (as passed to FoxyCart) FoxyCart (as of v060) will attempt to generate one from the name attribute. Prior to v060 a code value should be considered required for Google Analytics to properly track the items in your transactions.
  • Tracking your banner ads and email marketing links. Very cool, and you should definitely do it if you're going to do anything described below.
  • This is all for ga.js and not urchin.js. If you need to use urchin.js it should be similar to this, but the urchin.js Google Analytics code is deprecated at this point so you'll have to adapt these instructions as necessary.

Known Issues and Limitations

  • This code may not work correctly if you're doing direct-to-checkout (cart=checkout) links originating from outside the site being tracked by Google Analytics. For instance, if you have cart=checkout links in an email, the referrer or campaign may not be maintained. If this is an issue for you please let us know.
  • While http: hrefs will work for add-to-cart requests, the redirect from http to https will cause problems for GA. Ensure that all link href and form action attributes go to https URLs.

Changes To This Page

  • 2011-08-08: Critical change to the include code. Details on our forum. The important pieces are:
    On the cart, change this line:
      window.location.hash = fc_json.custom_fields['ga'];
    to this:
      window.location.hash = fc_json.custom_fields['ga'].replace( /\&/g, '&' );
    
    And this line:
      var href_link = $(this).attr('href') + fc_json.custom_fields['ga'];
    to this:
      var href_link = $(this).attr('href') + fc_json.custom_fields['ga'].replace( /\&/g, '&' );
    
    On the checkout, change this line:
      window.location.hash = fc_json.custom_fields['ga'];
    to this:
      window.location.hash = fc_json.custom_fields['ga'].replace( /\&/g, '&' );
    
    On the receipt, change this:
      window.location.hash = fc_json.custom_fields['ga'];
    to:
      window.location.hash = fc_json.custom_fields['ga'].replace( /\&/g, '&' );

    This has been changed in all the examples below.

Setup Your Tracking Code

The steps below are for the “standard” *box (like the default Thickbox/Foxybox) is used, or in other situations where you're loading the cart inside an iframe. If you're displaying the cart full screen, using a JSON(P) based cart, or are otherwise doing something custom you may need to modify this code, depending on your needs. As always, test test test.
Google Analytics has updated the tracking script block that you put on your site since this documentation was written, but it still calls on the same underlying ga.js file to perform functions. The code in this tutorial should still work the same and does not need to be modified (beyond using your own Analytics account number, etc.).

With a *.foxycart.com Subdomain

If your cart and checkout are at something like example.foxycart.com, follow the steps below. If you're using a custom subdomain and your checkout is at something like secure.example.com, skip to the next section.

  1. On Step 1 under Google Analytics “Instructions for adding tracking” in your Google Analytics account, select the “Multiple top-level domains” radio button. Don't use the new asynchronous code, as this tutorial is not designed to work with the older GA code. It should look something like this:
    <script type="text/javascript">
    var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
    document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
    </script>
    <script type="text/javascript">
    try {
    var pageTracker = _gat._getTracker("UA-XXXXXXX-X");
    pageTracker._setDomainName("none");
    pageTracker._setAllowLinker(true);
    pageTracker._trackPageview();
    } catch(err) {}</script>

    Make sure to replace the XXXXXXX-X bit with your account information. The important pieces are the following two lines, which should be above your trackPageview() call:

    pageTracker._setDomainName("none");
    pageTracker._setAllowLinker(true); 
  2. Don't add the Google Analytics code to your cart page or anywhere else just yet. We'll get to that later.
  3. Follow the steps below, "Set Up Everything Else".

With a Custom Subdomain (ie. secure.yourdomain.com)

If your cart and checkout are at a custom subdomain, something like secure.example.com, follow the steps below. If you're using the default *.foxycart.com domain, complete the section above and then skip this section.

  1. On Your Site:
    1. Because you're tracking users across multiple subdomains (ie. yourdomain.tld, www.yourdomain.tld, secure.yourdomain.tld) you'll need to change your tracking code slightly, as described in the Google Analytics docs. As of 20100108 Google actually allows you to select this when you get your tracking code. Under Step 1 choose the radio button that says “One domain with multiple subdomains”.
    2. Your tracking code (for your entire site, not just the FoxyCart pages) should look something like this (replacing the XXXXXXX-X and YOURDOMAIN.TLD with your own account information). The important piece is the _setDomainName(“.YOURDOMAIN.TLD”) bit (note the leading dot):
      <script type="text/javascript">
      var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
      document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
      </script>
      <script type="text/javascript">
      try {
      var pageTracker = _gat._getTracker("UA-XXXXXXX-X");
      pageTracker._setDomainName(".YOURDOMAIN.TLD");
      pageTracker._trackPageview();
      } catch(err) {}</script>
  2. Don't add the Google Analytics code to your cart page or anywhere else just yet. We'll get to that later.
  3. Follow the steps below, "Set Up Everything Else".

Set Up Everything Else

  1. First, a note about TESTING: Because Google Analytics doesn't allow you to undo or remove data you've collected, you want to make sure you get it right before you go adding it to your main profile. For this reason, we recommend doing the following steps on a new profile. Call it “Testing” or something, and make sure it's working correctly there before applying it to your main profile, otherwise you'll have a bunch of wrong data throwing things off.
  2. GA SETTINGS: PROFILE: Edit your Profile Settings in your Google Analytics Settings section. (You can get here by clicking the “Edit” link to the right of the profile name from your analytics dashboard, then click the “Edit” link to the right of the “Main Website Profile Information” heading.)
    1. Add fcsid to the “Exclude URL Query Parameters” in your analytics settings. (If you're using FoxyCart prior to v051, use PHPSESSID,fc_PHPSESSID instead.) Details here.
    2. Set it to “Yes, an E-Commerce Site” and set your currency as desired.
    3. You probably want to set your “Default Page” to index.html or index.php or etc. But make sure you understand what this means, as it affects stuff like yourdomain.com/ as well as yourdomain.com/dir/sub/. More info here and here.
  3. GA SETTINGS: GOAL: Go back to your Profile Settings and click “edit” on one of your four goals. It doesn't matter which, but Goal #1 will show up by default in most of your GA reports, so if this is your only (or your primary) goal, you probably want to set it up as Goal #1.
    1. Enter a “Goal Name” that makes sense to you, like “Purchase Conversion”
    2. Make sure it's set to “Active” up top.
    3. Set the “Goal Type” to “URL Destination”
    4. Switch the Match Type to “Exact Match”
    5. Enter for your Goal URL: /receipt
    6. Create a funnel for this Goal:
      1. Step 1: use /cart for the URL and “Cart” for the Name. (You won't have this step if you are using “direct to checkout” with the parameter “cart=checkout”). (Required step?… uh… I think you should check this box)
      2. Step 2: /checkout for the URL and “Checkout” for the Name.
    7. Hit the “Save Changes” button down at the bottom. (The receipt page is the goal, so you don't need to add it in the steps.)
  4. ON YOUR SITE:
    1. On your own site, add the following below your GA script tags:
      <script type="text/javascript" charset="utf-8">
         	jQuery(function($){
      		$('a.foxycart').click(function(){
      			if (!$(this).attr('href').match('cart=checkout')) {
      				pageTracker._trackPageview('/cart');
      			}
      		});
      		$('form.foxycart').submit(function(){
      			if (!$(this).serialize().match('cart=checkout')) {
      				pageTracker._trackPageview('/cart');
      			}
      		});
      	});
      	function fc_BuildFoxyCart() {
      		// Add the Google Analytics data to the FoxyCart session
      		$.getJSON('https://' + FoxyDomain + '/cart?cart=view' + fc_AddSession() + '&h:ga=' + escape(pageTracker._getLinkerUrl('', true)) + '&output=json&callback=?', function(data){});
      	}
      </script>

      Note that if you're already using an fc_BuildFoxyCart() function elsewhere you'll need to add this .getJSON line to that function, or tie it in wherever appropriate. The key is that we want to keep the FoxyCart session up to date with the GA session data. Also note that this line replaces the need to set up crosslinks/forms as Google describes in this article on tracking multiple domains. The JSONP code that we'll use throughout the cart-checkout-receipt process ensures that the Foxycart session has the correct GA session values.

  5. CART: Add the following above the </body> tag on your CART template. Do not include the GA script calls on your cart template or you'll register that page twice (the visit to the cart page is tracked by a Javascript call on your product page):
    <script type="text/javascript" charset="utf-8">
    	jQuery(function($){
    		if (fc_json.custom_fields['ga']) {
    			$('a.fc_link_nav').each(function(){
    				var href_link = $(this).attr('href') + fc_json.custom_fields['ga'].replace( /\&amp;/g, '&' );
    				$(this).attr('href', href_link);
    			});
    		}
    	});
    </script>
  6. CHECKOUT:
    1. Next you'll add code to the bottom of your checkout template. You'll use your main GA tracking code from your site (and not the jQuery piece or the fc_BuildFoxyCart piece) plus additional code that captures the tracking parameters. Don't grab the code from the “CART” section above. The example below shows what you'll need on your checkout template.
    2. Change the bottom line from pageTracker._trackPageview(); to pageTracker._trackPageview(“/checkout”);
    3. Above that pageTracker._trackPageview(“/checkout”); line, add this:
      pageTracker._setAllowLinker(true);
      pageTracker._setAllowAnchor(true);
    4. Add this right before the “try” statement:
      // Ensure the GA info is in the URL //
      if (window.location.hash.search(/utma/) == -1 && typeof(fc_json.custom_fields['ga']) != "undefined") {
      	if (fc_json.custom_fields['ga'].length > 0) {
      		window.location.hash = fc_json.custom_fields['ga'].replace( /\&amp;/g, '&' );
      	}
      }
    5. Your finished code for the checkout will look like this (of course you must replace the XXXXXXX-X with your appropriate Google Analytics account info):
      • If you're using a custom subdomain, make sure to replace the .YOURDOMAIN.com with the appropriate code (retain the leading dot – it's essential!):
        <script type="text/javascript">
        var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
        document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
        </script>
        <script type="text/javascript">
        // Ensure the GA info is in the URL //
        if (window.location.hash.search(/utma/) == -1 && typeof(fc_json.custom_fields['ga']) != "undefined") {
        	if (fc_json.custom_fields['ga'].length > 0) {
        		window.location.hash = fc_json.custom_fields['ga'].replace( /\&amp;/g, '&' );
        	}
        }
        try {
        var pageTracker = _gat._getTracker("UA-XXXXXXX-X");
        pageTracker._setDomainName(".YOURDOMAIN.com");
        pageTracker._setAllowLinker(true);
        pageTracker._setAllowAnchor(true);
        pageTracker._trackPageview('/checkout');
        } catch(err) {}</script>
         
        </body>
        </html>
      • If you're using a *.foxycart.com domain:
        <script type="text/javascript">
        var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
        document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
        </script>
        <script type="text/javascript">
        // Ensure the GA info is in the URL //
        if (window.location.hash.search(/utma/) == -1 && typeof(fc_json.custom_fields['ga']) != "undefined") {
        	if (fc_json.custom_fields['ga'].length > 0) {
        		window.location.hash = fc_json.custom_fields['ga'].replace( /\&amp;/g, '&' );
        	}
        }
        try {
        var pageTracker = _gat._getTracker("UA-XXXXXXX-X");
        pageTracker._setDomainName("none");
        pageTracker._setAllowLinker(true);
        pageTracker._setAllowAnchor(true);
        pageTracker._trackPageview('/checkout');
        } catch(err) {}</script>
         
        </body>
        </html>
  7. RECEIPT:
    1. Set up a receipt template separate from your checkout template if you haven't already done so. It can be basically identicaly to your checkout template, except the Google Analytics code must be changed and we're adding a few extra placeholders to track the sale.
    2. Copy your GA code from your site and not from your Checkout template above. We don't want that whole window.location.hash bit. This is important.
    3. Change the bottom line from pageTracker._trackPageview(); to pageTracker._trackPageview(“/receipt”);
    4. Beneath your GA script tags, add ^^analytics_google_ga^^. This generates code that tracks the sale and actually tracks the ecommerce transaction. (If you're using urchin.js, use ^^analytics_google_urchin^^.) Because your store's receipts can be revisited by your customers, you'll need to wrap the ^^analytics_google_ga^^ (or _urchin) inside additional placeholders to ensure it only gets loaded on the initial receipt view. These placeholders are described on the placeholders documentation. It should look like this:
      ^^receipt_only_begin^^
      ^^analytics_google_ga^^
      ^^receipt_only_end^^

      Without these ^^receipt_only_ placeholders a single transaction could be logged multiple times, throwing off your data.

    5. Your finished code for the receipt should look something like this, obviously replacing the XXXXXXX-X with your appropriate Google Analytics account info:
      • If you're using a custom subdomain, make sure to replace the .YOURDOMAIN.com with the appropriate code (retain the leading dot – it's essential!):
        <script type="text/javascript">
        var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
        document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
        </script>
        <script type="text/javascript">
        try {
        var pageTracker = _gat._getTracker("UA-XXXXXXX-X");
        pageTracker._setDomainName(".YOURDOMAIN.com");
        pageTracker._trackPageview('/receipt');
        } catch(err) {}</script>
         
        ^^receipt_only_begin^^
        ^^analytics_google_ga^^
        ^^receipt_only_end^^
         
        </body>
        </html>
      • If you're using a *.foxycart.com domain:
        <script type="text/javascript">
        var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
        document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
        </script>
        <script type="text/javascript">
        try {
        var pageTracker = _gat._getTracker("UA-XXXXXXX-X");
        pageTracker._setDomainName("none");
        pageTracker._trackPageview('/receipt');
        } catch(err) {}</script>
         
        ^^receipt_only_begin^^
        ^^analytics_google_ga^^
        ^^receipt_only_end^^
         
        </body>
        </html>
      • The ^^analytics_google_ga^^ will output the cart array, as described here. GA will pick up on this automatically.
      • If you're not using FoxyCart v050+ you must remove the ^^receipt_only_begin^^ and ^^receipt_only_end^^ tags, as they aren't supported.
      • As noted above, if your products don't have a code parameter passed in to FoxyCart (which outputs as the SKU in the Google Analytics tracking), they may not record correctly. Also, spaces in the code (SKU) parameter may cause problems. FoxyCart attempts to automatically set a SKU based on the name attribute if no code value is present, but we recommend setting explicit code values if you care.
  8. TEST: This should work, but testing is always required. If you encounter any issues please post in the FoxyCart forum.

Testing

Checking Cookies

If you follow the instructions above, you'll have no problems. If you do, check your code and then review these tips for troubleshooting.

It's often difficult to troubleshoot because it takes upwards of four hours for any transactions to appear in Google Analytics. So if you set up FoxyCart to be tracked in Google Analytics, and you try a few test transactions, it will take at least four hours before you can see if things are working correctly. There's a faster way. You can look directly at the cookies set by Google Analytics.

You'll need to be able to view cookies (and clear or reset cookies) in your web browser. If you're using Firefox, you can install Chris Pederick's Web Developer extension for Firefox: http://chrispederick.com/work/web-developer/.

Visit your product order page. From the Web Developer toolbar, select “View Cookie Information” from the Cookies mneu.

GA sets cookies named utma, utmb, utmc, and utmz. Each has a “host” parameter as well as a value. See a detailed description of the information stored in these cookies.

The GA tracking code you add to your product page determines what the host value will be. The simplest pageTracker._trackPageview() will give you .mysite.com as a host parameter (with a leading dot). Adding pageTracker._setDomainName(“none”) will give you www.mysite.com as a host parameter if the domain is www.mysite.com. You can check the GA cookies to make sure the “host” is what you expect.

Each cookie will have a value that begins with a “hash” that encrypts the host value. The domain hashing functionality in Google Analytics creates a hash value from your domain, and uses this number to check cookie integrity for visitors. If you have multiple sub-domains, such as example1.example.com and example2.example.com, and you want to track user behavior across both of these sub-domains, you would turn off domain hashing so that the cookie integrity check will not reject a user cookie coming from one domain to another. If you add pageTracker._setDomainName(“none”) or pageTracker._setAllowHash(false) to your GA tracking code, each cookie will have the integer “1” as its hash value. If you are tracking across multiple domains and you don't see “1” as the first integer in a GA cookie value, you may have a problem.

Take a close look at the value for the utmz cookie. This cookie encodes all the essential details of how a visitor came to the site, such as referring site or search keyword. This is the data that you want to see tracked all the way to your final order receipt page.

Add your product to your cart and click through to Checkout. Check your cookie information again. You should see a new host (example.foxycart.com) and the utmz value should contain the same tracking data that you saw in the utmz cookie for your product page. If it does not, for example, if it shows utmcsr=(direct), something may be configured incorrectly or broken.

Keep in mind that cookies are persistent. If you are testing, you will need to “Delete Domain Cookies” on your checkout page and product page prior to initiating a new test.

Site Tools