How To Run Split Tests on Outbound Links with Google Tag Manager

min read

It’s been a while since I last used Google Optimize. After logging in recently I was quite impressed to see just how far the platform has come. If you’re not familiar (or haven’t looked at it in a while), I highly recommend checking it out. Here’s an article I wrote a while back that should give you an understanding of how it could be used for various user experience experiments.

Despite the vast customization options that Google Optimize now provides, there are some experiments that Google Optimize still can not perform. When I can’t run the tests I need on Google Optimize, I turn to Google Tag Manager, a tactic I thought I’d share today.

Where A/B Platforms Fail

When a client asked for help setting up a split test, also known as a redirect test, I immediately thought of Google Optimize to run what seemed like a pretty straightforward experiment. A split test involves using different URLs or paths in the customer journey to see how positively or negatively it affects the end objective.

However, the client wanted to understand more about their conversion rates on outbound affiliate links in their articles, and whether they might convert more by sending users to internal pages that reviewed affiliates first.

This presented a problem. In order to run experiments with Google Optimize (and other A/B testing platforms), you are required to install code that allows the respective platforms to function and manipulate the DOM of your website.

It quickly became clear that I couldn’t ask any external affiliate site to install code from Google Optimize, VWO, Optimizely, or any other A/B testing platform. So I turned to the next best cost-effective alternative; JavaScript and Google Tag Manager.

Identifying a Sitewide Element

My first hurdle was identifying where all of the affiliate links on their site were. The client has thousands of pages. Across these pages, there are specific affiliate links within articles. The client had asked me to set up this experiment for six unique affiliate links, and there was no way to easily identify which pages contained them. So my first goal was to identify which pages contained the specific affiliate links.

The approach below will help you identify almost any element in the HTML of the page.

First, I set up Google Tag Manager to deploy a Custom HTML Tag that contained a small JavaScript code. This code uses getElementbyId to look within a specific section on the page using its id, in this case <div id=’content’>. This was the section of the page that contained the body of the articles and within that, the affiliate links. When one was found, I pushed a value, in this case the specific affiliate URL, into the dataLayer:

You could use any value here, but since I knew I was setting this up for six specific URLs I found it easiest to use the affiliate URL as the value.

Here’s how this tag looked when compiled in Google Tag Manager:

I added this script, (again customized for each affiliate URL) using Custom HTML Tags, firing on All Pages (Page View).

With this in place, I was able to leverage each instance of AffiliateLinkFound in the dataLayer to deploy six other Custom HTML Tags that contained the split test JavaScript code. Additionally, this initial identification method helped prevent me from deploying the split test experiment unnecessarily across the entire site.

The Data Layer Variable and Trigger

In order to create the trigger, I first needed to create a Data Layer variable that acknowledged when an affiliate URL was found.

In Google Tag Manager, I selected the Data Layer Variable type and simply added the name designated in the tag, in this case, AffiliateLinkFound. 

From here I was able to set up the trigger using Window Loaded that fired when the dataLayer variable AffiliateLinkFound contained one of the affiliate links:

Now that I was able to identify pages that contained the affiliate URLs and I had a trigger ready to fire, I moved onto setting up the JavaScript code that ran the actual test.

Split URL Test – JavaScript Code

The JavaScript code below accomplishes the following:

  1. In HTML of the page, find all instances of
    a href=””
  2. For each instance that exactly matched (i.e. did not contain any other query string parameters – another factor I had to take into account), use the replace function (outlined below as replaceFn).
  3. Then replace each instance on the page (of which there could be three or four of the same affiliate link) at random with either an internal link to a review of the affiliate ( or just keep the link the same (i.e.
    • You will notice that the internal link below also contains a query string parameter (?test=true) this allowed me to keep track of the experiment via Google Analytics.

Here’s how the whole code looks:

  // Gather all hrefs on the page containing
  // If found, for each link that *exactly* matches add them to the replace function:
  .forEach(function (el) {
    el.href = el.href.replace(/^https:\/\/affiliate\.com\/link\/$/g, replaceFn);
  // For each instance found, randomly choose between one of the two URLs below to replace the original with:
function replaceFn() {
  return [
  ][Math.floor(Math.random() * 2)];

Here’s how it looks compiled in Google Tag Manager with the trigger I set up earlier:

To recap, once published, I should expect this tag to accomplish the following:

  • Find all pages on the site that contain a specific element, in this case, all instances of a href=””.
    • When found, a dataLayer value is generated.
  • Then the custom split URL JavaScript tag is deployed on all pages that contain the dataLayer value as defined in the trigger.
  • Lastly, all instances of the element (i.e affiliate URLs) on the pages that contain them will be altered at random to one of the two URLs I defined in the replace function.

The Results

From here I was able to open up Google Analytics to compare and contrast the conversion rates alongside data provided from the client’s affiliates, to understand whether an endorsement in the format of a review from the client, as opposed to simply sending users directly to affiliate sites from in-article links, helped to increase conversion rates with affiliates.

More Ways to Experiment

While this method originally set out to solve a specific issue, you could use this code for other experiments if you didn’t want to install Google Optimize or another testing platform.

  • Replace All – You could also modify this script to simply replace all of the affiliate links (or another element) with one choice, instead of choosing from two or more. To do that you would simply modify the replace function to return a single item. That would look something like this:

The following suggestions may cause element flashing for users. In other words, they may see a noticeable change if the original element has loaded before the script is able to change it for the experiment. This would be especially noticeable over slower connections and is also often a concern with other A/B testing tools. With that in mind, you may want to experiment with elements below the viewport for these particular methods to see how they perform.

  • Experiment with Images – Change the source URL for an image on a page, or perhaps a global image across multiple pages with another image.
    • Since there is no query string parameter attached to the image URLs, you will want to make sure you know which version of an image may have performed better. I recommend leveraging the code at the beginning of this article that identifies an element on the page and pushes values into the dataLayer for each image. From there you can set up an event in Google Analytics for each respective image URL to correlate with conversion data.
  • Experiment with Calls to Action – Perhaps you want to understand whether a certain color or phrase works better for a button. You can leverage this code to switch out different CSS classes or phrases of text.

With Google Tag Manager you can deploy tags based on a seemingly endless number of factors. For example, you can limit your experiments to specific pages, users and even actions.

Again, while I don’t think this method should be a replacement for A/B testing platforms, it did help me solve a unique problem that other services did not seemingly provide a solution for in perhaps the most performance-friendly (and cost-effective) way possible.

If you use this code, I’d love to hear how you applied it.