Expert Optimisation Support Available
Need Help Running Tests?
Our specialists are ready to help you optimise your online experience.

Launch Fast, Lightweight A/B/n Tests
with Our Free GTM MVT Script

Say goodbye to old testing tools. This script lets you deploy multivariate tests directly through Google Tag Manager, with zero vendor lock-in. No SDKs. No flicker. No waiting for approval. Just fast experimentation, your way.

True multivariate logic
Test multiple elements and variants at once, not just A vs B.
Works with GTM only
No added scripts, no monthly fees. Fully customisable.
Includes setup template
Get started in minutes with our pre-configured GTM file.
Track results in GA4
Test data flows into Google Analytics or BigQuery seamlessly.

Includes a ready-to-import GTM template. Set up once, test forever.

Use the Free MVT Tool

How to Use the Free MVT Script

  1. Give your test a unique test code (e.g. AAA001).
  2. Choose how many variants you want (e.g. 4 = control + 3 variations).
  3. Add your JavaScript for each variant at the top of the code.
  4. Paste the whole block into a Custom HTML Tag in GTM and trigger it on your test page.
  5. Watch the results roll into your GA4 reports!

πŸ’‘ You can even force a variation by adding ?mvt=variation1 to your URL for testing/debugging.

<script>
(function() {
  /* ==== MULTIVARIATE TEST SETUP ==== */
  /* 
     βœ… Update the following values for your test:
     1. testCode        β†’ Unique test identifier (must be unique per test!)
     2. testVersion     β†’ Optional version tag to prevent conflicts when re-running a test
     3. variants        β†’ Total number of variants (e.g. 4 = control + 3 variations)
     4. testInclusionRate β†’ Between 0 and 1 (e.g. 1 = 100%)
     5. Define your control() and variationX() functions below
  */

  var testCode = 'AAA001'; // Unique code for this test
  var testVersion = 'v1';  // Change this if you re-run the same test later
  var variants = 4;
  var testInclusionRate = 1;
  var cookieDays = 7;

  // ==== VARIATION FUNCTIONS ====
  window.control = function () {
    console.log(testCode + ' Control Running');
    // Your control logic here
  };
  
  window.variation1 = function () {
    console.log(testCode + ' Variation 1 Running');
    // Your variation 1 logic here
  };

  window.variation2 = function () {
    console.log(testCode + ' Variation 2 Running');
    // Your variation 2 logic here
  };

  window.variation3 = function () {
    console.log(testCode + ' Variation 3 Running');
    // Your variation 3 logic here
  };

  // ==== DO NOT EDIT BELOW THIS LINE ====

  var cookieKey = testCode + '_' + testVersion;

  function setCookie(name, value, days) {
    var expires = new Date();
    expires.setTime(expires.getTime() + (days * 24 * 60 * 60 * 1000));
    document.cookie = name + '=' + encodeURIComponent(value) + '; expires=' + expires.toUTCString() + '; path=/; SameSite=Lax';
  }

  function getCookie(name) {
    var match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
    return match ? decodeURIComponent(match[2]) : null;
  }

  var urlParams = (function () {
    var params = {};
    var query = window.location.search.substring(1);
    var pairs = query.split("&");
    for (var i = 0; i < pairs.length; i++) {
      var parts = pairs[i].split("=");
      if (parts.length === 2) {
        params[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]);
      }
    }
    return params;
  })();

  var forcedVariant = urlParams['mvt'];

  function runVariant(variantName) {
    console.log(testCode + ': Running ' + variantName);

    window.dataLayer = window.dataLayer || [];
    window.dataLayer.push({
      event: 'MVT Test',
      eventCategory: 'MVT Test',
      eventAction: testCode,
      eventLabel: testCode + ' ' + variantName
    });

    setCookie(cookieKey, variantName, cookieDays);

    if (typeof window[variantName] === 'function') {
      window[variantName]();
    } else {
      console.warn('No function defined for ' + variantName);
    }

    if (typeof window.dispatchEvent === 'function') {
      window.dispatchEvent(new Event('mvt-loaded'));
    }
  }

  var existing = getCookie(cookieKey);

  if (forcedVariant) {
    runVariant(forcedVariant.toLowerCase());
  } else if (existing) {
    runVariant(existing);
  } else if (Math.random() < testInclusionRate) {
    var index = Math.floor(Math.random() * variants);
    var variantName = index === 0 ? 'control' : 'variation' + index;
    runVariant(variantName);
  } else {
    console.log(testCode + ': User not included in test');
  }

  // === βœ… Console credit ===
  console.log('Code on this page was developed by www.netimpression.co.uk πŸš€');

})();
</script>

‍

✨ This script was developed by Net Impression - making analytics simpler, sharper, and free where it counts. Feel free to copy, share, or extend it - just leave the credit in the console! You can also view the source on GitHub or contribute improvements.

Ready to fix your tracking or run smarter tests? Let’s talk.

Whether you need to fix your tracking, improve your reporting, or run better experiments, we help businesses of all sizes turn analytics and CRO into a real growth engine. Get in touch to see how better data and faster testing can accelerate your results.
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.