Google A/B Testing with ExpressionEngine, Structure & Freebie

by Jonathan Longnecker

It’s been far too long since we had a proper ExpressionEngine tutorial here so without further adieu I present to you a solution for running Google A/B Tests with a Structure setup. Be warned, if you’re not familiar with how Structure works or basic EE templating you might get lost. I just can’t cover all of that here.

We had the pleasure of working with a kick awesome company called Firmex a few months ago and built them out a sweet Structure based site. We didn’t actually design this one - credit goes to Laura Wills at Messenger Design for that. But we did do all the HTML/CSS and ExpressionEngine work.

One of the main things Firmex wanted to be able to do was use Google’s A/B Optimizer to track the effectiveness of just about every page on the site. Wait, what – every page I hear you say? That’s right. And that’s some serious flexibility right there. But let’s start with exactly what A/B testing is.

A/B Testing - A Quick Overview

Firmex A/B Example

Let’s say you had the best homepage ever on your site. But you weren’t sure if the picture and header at the top of the page were sending the right message. With the A/B testing you could setup multiple versions with different pictures and headlines and track the results to see which is the most effective.

In order to do all this you need a few things:

  • A Google Account
  • Use that account to signup for an optimizer account
  • Create 2 or more versions of the page you want to test
  • Have a “success” page - or a shared call to action among all the pages. The version that sends the most people to the success page wins. Capish?
  • Have access to put some javascript in the headers of each of these pages.

The process on Google’s site is really pretty straightforward and I don’t want spend a lot of time there. We need to be figuring out how to do this in EE with Structure.

What Structure Does Right

It’s no secret that I love Structure. We use it for a lot of our projects. And Firmex was the kind of client that was actually going to use their site and be building out pages left and right. So Structure was the perfect fit for them. In fact, creating multiple versions of a page is a snap with Structure. So what’s the problem? Navigation.

The Problem - Navigation

Let’s say you have a page at the url and variations at and First. of all you’ve just created another level of navigation that Structure is going to want to show. And you don’t want to have your alternate pages showing in the navigation. Also, you’ll ideally want your navigation to stay highlighted on the top level no matter which of the alternate pages you’re on.

So what do we do? Thankfully, I know Jack McDade - the dude that made Structure. And after quite a few long conversations we figured out a really easy way to make this work.

But first, our goals:

  • Create multiple alternates of a main page
  • Be able to put the appropriate Google tracking code into each one
  • Keep navigation highlighted for the main version of the page
  • Don’t show the alternate pages anywhere in the navigation

Start with Structure

First, you’ll want to go grab the newest version of Structure (v. 3.0.3).

We can actually get 80% of the way there with Structure alone. Make sure you have a custom field to paste your Google code into along with any other fields you need. Now we already know it’s easy to create pages but with a new status type we can easily exclude them from any navigation trees. In our example we created a status called “Alt.” Original, I know. In order for this all to work you’ll need to make your alternate pages children of the main page you want to create the variations on.

Now the cool thing is that Jack created a class on the list elements in structure that maps to the status. So in our case, the class is status-alt. This means that we can apply a different color in the CSS so alternate pages don’t get confused with main pages.

Showing Firmex Alt Status Color

So this is working pretty well so far. We can get to our alternate pages, we don’t have a bunch of extra random navigation. We just need to keep the main navigation highlighted. Enter Freebie.

The Missing Link: Freebie

Apparently I missed the Freebie train a while back. You can do some crazy stuff with this Add-on. Basically it tells EE to ignore certain segments in the URL so you can trigger template behavior with the Freebie segments. Very useful if you’re using something like Structure that’s very strict with it’s URL’s.

Until the latest version of Structure, Freebie wouldn’t have helped us out of the box, but Jack added a super secret undocumented tag called {structure:freebie:entry_id} that looks for a Freebie segment and tries to match it with a Structure uri and grab the entry_id.

Now go into Add-Ons > Extensions > Freebie > Settings and under Freebie Segments add alt-*. This tells ExpressionEngine to ignore any URL segments with “alt-xx” in them. So you could do “/alt-1, /alt-2, /alt-3” and so on.

Once you’ve done this your alt pages probably won’t load anymore because Structure is ignoring that last segment and Freebie has taken it over. Have no fear. That super secret undocumented tag is coming to the rescue!

We just use the {structure:freebie:entry_id} to grab that entry_id and show the correct content. In my case I was using a lot of template embeds so we can pass it through as a parameter as well. Don’t forget to include that alt status!


 {exp:channel:entries channel="content" status="open|Alt" 

    <meta name="description" content="{desc}" />
    <title>{exp:structure:titletrail separator="|"}</title>   

    {js_campaign} (for Google Code)





    <div id="content">


    </div><!--End Content-->

    {embed="global/sidebar" entry_id="{structure:freebie:entry_id}"}

    {embed="global/footer" entry_id="{structure:freebie:entry_id}"}



And on the embedded template side:

{exp:channel:entries channel="content" limit="1" 
  status="open|Alt" entry_id="{embed:entry_id}"}

    <!--Your EE Content-->


And that’s it! Because Structure is ignoring that Freebie segment the navigation will stay highlighted for the parent page and all will be good.

Quick Overview

If all that was a bit too meandering for you, here’s a condensed version:

  1. Get the latest versions of ExpressionEngine, Structure and Freebie.
  2. Setup your content channel with Alt status and custom field for tracking code from Google.
  3. Go into the EE CP in Add-Ons > Extensions > Freebie > Settings and under Freebie Segments add alt-*.
  4. Create main page.
  5. Create alternate versions of the main page as child pages with the Alt status and Structure URL’s of /alt-xx.
  6. Setup your Structure template like normal, but use the {structure:freebie:entry_id} to grab the entry_id from the Freebie segment as needed.
  7. Make sure you can get to each of your new URL’s.
  8. Go through the Google Optimizer steps and use the code they give you to paste back into to each page entry.
  9. Test the crap out of it and see which one is best!
  10. Make wads of cash and rule the world.

Huge, massive, radtastic props to Jack McDade for helping me figure this one out and soiling his precious Add-On with my hacks smile You rock, sir!

I hope this helps someone else out there trying to get Google A/B Testing working with EE and Structure. It really works great.

July 05, 2011



  1. Sorry if this is a silly question, but how do people get to the different variations of the page? Or are these all pages that are linked to from offsite sources, like Adwords?

  2. Hey John,

    Not a silly question at all. When you put in all the tracking code that Google gives you it knows to randomly serve up a different page each time someone loads it.

  3. This is very useful guys, very useful indeed.

    For the folks that haven’t used Structure before - then check out the screencast I did for EE Spotlight on

  4. Ah right, thanks Jonathan, good to know.

  5. @John you’re welcome!
    @Steven cool man thanks for sharing smile

  6. Awesome tutorial! I’ve been missing the EE tuts around here.

    On a side note, in paragraph 5 under The Missing Link, it says ‘enry_id’ instead of ‘entry_id’ - thought you might want to adjust. And feel free to remove this part of my comment if/when you do!

  7. @Jimmy, Thanks man! Got it fixed.

  8. great tutorial.

  9. Excellent write up, very handy indeed for AB testing stuff.


  10. Informative! Just what I was looking for.

Behold our Amazing Portfolio

Check it Out