Table of Contents
- 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:
Assumptions
- 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.
- 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 thecode
parameter in FoxyCart. If your products do not include acode
value (as passed to FoxyCart) FoxyCart (as of v060) will attempt to generate one from thename
attribute. Prior to v060 acode
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 noturchin.js
. If you need to useurchin.js
it should be similar to this, but theurchin.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 havecart=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:
href
s will work for add-to-cart requests, the redirect fromhttp
tohttps
will cause problems for GA. Ensure that all linkhref
and formaction
attributes go tohttps
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
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.
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.
- 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 yourtrackPageview()
call:pageTracker._setDomainName("none"); pageTracker._setAllowLinker(true);
- Don't add the Google Analytics code to your cart page or anywhere else just yet. We'll get to that later.
- 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.
- On Your Site:
- 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”. - Your tracking code (for your entire site, not just the FoxyCart pages) should look something like this (replacing the
XXXXXXX-X
andYOURDOMAIN.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>
- Don't add the Google Analytics code to your cart page or anywhere else just yet. We'll get to that later.
- Follow the steps below, "Set Up Everything Else".
Set Up Everything Else
- 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.
- 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.)
- Add
fcsid
to the “Exclude URL Query Parameters” in your analytics settings. (If you're using FoxyCart prior to v051, usePHPSESSID,fc_PHPSESSID
instead.) Details here. - Set it to “Yes, an E-Commerce Site” and set your currency as desired.
- 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.
- Enter a “Goal Name” that makes sense to you, like “Purchase Conversion”
- Make sure it's set to “Active” up top.
- Set the “Goal Type” to “URL Destination”
- Switch the Match Type to “Exact Match”
- Enter for your Goal URL:
/receipt
- Create a funnel for this Goal:
- 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) - Step 2:
/checkout
for the URL and “Checkout” for the Name.
- 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.)
- ON YOUR SITE:
- 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.
- 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( /\&/g, '&' ); $(this).attr('href', href_link); }); } }); </script>
- CHECKOUT:
- 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 thefc_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. - Change the bottom line from
pageTracker._trackPageview();
topageTracker._trackPageview(“/checkout”);
- Above that
pageTracker._trackPageview(“/checkout”);
line, add this:pageTracker._setAllowLinker(true); pageTracker._setAllowAnchor(true);
- 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( /\&/g, '&' ); } }
- 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( /\&/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( /\&/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>
- RECEIPT:
- 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.
- 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. - Change the bottom line from
pageTracker._trackPageview();
topageTracker._trackPageview(“/receipt”);
- 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 usingurchin.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. - 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 theSKU
in the Google Analytics tracking), they may not record correctly. Also, spaces in thecode
(SKU
) parameter may cause problems. FoxyCart attempts to automatically set a SKU based on thename
attribute if nocode
value is present, but we recommend setting explicit code values if you care.
- 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.