Using Visual Website Optimizer with Google Tag Manager



Recently, I was working with a client to integrate Visual Website Optimizer (VWO) with Google Tag Manager. I started by following the integration guide on VWO’s support pages, but ran into a few issues that required a creative workaround.

Not only did the timing of the VWO loading present issues, but I found that the specific data that is supposed to made available on the dataLayer wasn’t being made available.

Follow the instructions below to fix both of the problems!

When to Fire

I had hoped to simply add a custom dimension to our existing Pageview tag in GTM that would add in the necessary information from VWO. However, Since both VWO and Google Tag Manager are loaded asynchronously, we ran into an issue where Google Tag Manager would inconsistently load and execute before VWO was finished loading.

This would mean that object _vwo_exp would not be appended to the page yet by VWO. This resulted in the custom dimension only being populated part of the time.

We could either delay the Pageview tag (not recommended) or come up with a better option. Luckily, VWO passes an event to the dataLayer to let us know when it has finished working. We decided to fire a Google Analytics event when that gets pushed, which fixes our first issue.

What Information to Include

Now that we decided to use an event, we had to decide what information to include. VWO is supposed to be pushing information about the current variation to the dataLayer in addition to the event. Unfortunately, we found this wasn’t working properly.

So instead of following the support guide, I had found that we could grab the same information with a custom JavaScript Macro.

What’s happening in this snippet of code is very simple. We want to check to make sure that the _vwo_exp object is present on the page. After that we work through each of the keys. The keys key – is actually evaluated as each campaign inside of the parent object.

We then check to make sure that the user was not excluded from the A/B test. If the user was not excluded from the A/B test, we push the key and the value into an array. Once we check for the variants of each test running we then make the array into a string.

Just a note, If you are excluded from a test, once the _vwo_exp object is appended to the page it won’t have the “combination_chosen” key inside of it, so this macro will just return null.

Sending It All to Google Analytics

Now that we know when to fire, and we have the information to pass in, we need to create the tag that sends it all to GA.

Create a new tag with type of “Universal Analytics” and choose a track type of “Event”. You can fill in the Category name and Label name with anything you like. I decided to use the {{url path}} macro to pass exactly what page this was happening on.

Remember to set Non-Interaction to TRUE, as we don’t want these events affecting our bounce rate!


For Action, you will want to use your recently-created macro. I named this “vwo get experiment,” but you can call this anything you like.

Screen Shot 2014-11-03 at 9.27.01 AM

Now that we have the info, we can still choose to pass this is a Custom Dimension. Make sure you set this up in Google Analytics first, then set the index accordingly and the put the same recently made macro into the Dimension field.

Screen Shot 2014-11-03 at 9.27.16 AM

The next step you need to do is head over to VWO, go to your campaigns settings and check the Google Tag Manager integration. The reason for this is so that the VWO script knows to push the VWO event to the page when the script is loaded.

Finally, you need to set up the rule for so that the event can be triggered.

Screen Shot 2014-11-03 at 9.43.34 AM

That’s it, it’s very simple and can be done with only a handful of lines of code and a little Google Tag Manager magic!

Justin is a former LunaMetrician and contributor to our blog.

  • Hi Justin –

    You’ve got a typo in your code:
    (expString.length > 0 ? expString = ‘|’ + expString.join(‘|’) + ‘|’ : expString = null);

    should be:
    (expString.length > 0 ? expString = ‘|’ + expString.join(‘|’) + ‘|’ : expString = null);

    Oh, pre, you’re so silly sometimes.

  • Andy Batten

    I’ve run into the same frustrating issues; I like this solution. One thing I see as an issue, though, is by combining the string of tests the user is exposed to, if they are exposed to 2 tests on one page, and 1 of the same previous tests on another page, even though the user was still part of that same test the value of the visitor-level custom dimension will change, inflating your Dimension report.

    Example values in Dimension:

    Page 1: ​​|48:2|58:2|
    Page 2: |48:2|

    Two different values in your User-level dimension, but same user. Any ideas?

  • Zach Shearer

    Sara, can you clarify where the error is? Your two code examples appear exactly the same.

  • Zach Shearer

    Anyone else have issues with the vwo event never being sent by Visual Website Optimizer?

  • Dejan

    I am running into the same issue.

    However I have done the workaround a bit different, but it comes down to the same. I want to automate the macro needed to set a certain campaign to a certain index.

    But have not yet found a solution how to set them to different index’s correctly.

    Have you stumbled upon a solution by any chance?

  • Santosh Rajan

    You can use anti test collision method using the cookies so that an user is exposed to only one test on a page

Contact Us.

Follow Us



We'll get back to you
in ONE business day.
Our Locations
THE FOUNDRY [map] LunaMetrics

24 S. 18th Street
Suite 100

Pittsburgh, PA 15203


4115 N. Ravenswood
Suite 101
Chicago, IL 60613


2100 Manchester Rd.
Building C, Suite 1750
Wheaton, IL 60187