Quick Install

Installing the A vs B snippet takes two tags. Copy your snippet from Project Settings, paste it into your site's <head>, and you're done.

Your snippet lives in Project Settings → Snippet, copy it from here.

The snippet

Your snippet is pre-generated in your project settings. It looks like this, with your real key in place of YOUR_SNIPPET_KEY:

HTML
<script>window.avsb=window.avsb||{};window.avsb.q=window.avsb.q||[];window.avsb.ready=window.avsb.ready||function(f){window.avsb.q.push(f)};window.avsb.on=window.avsb.on||function(n,f){var t=['on',n,f];window.avsb.q.push(t);return function(){t[0]=null}};window.avsb.consent=window.avsb.consent||{set:function(s){window.avsb.q.push(['consent.set',s])},get:function(){return{}}};window.avsb.track=window.avsb.track||{};['event','segment','purchase','cart'].forEach(function(m){window.avsb.track[m]=window.avsb.track[m]||function(a,b){window.avsb.q.push(['track.'+m,a,b])}});(function(){window.avsb._t0=Date.now();window.avsb._df=fetch('https://cdn.avsb.cloud/YOUR_SNIPPET_KEY/datafile.json').catch(function(){});var d=document,e=d.documentElement,s=d.currentScript,a=s&&s.getAttribute('data-avsb-timeout'),t=a==null?3000:+a;if(!(t>0)||window.avsb.version)return;e.style.opacity='0';e.style.pointerEvents='none';window.avsb._t=setTimeout(function(){e.style.removeProperty('opacity');e.style.removeProperty('pointer-events')},t)})();</script><script src="https://cdn.avsb.cloud/snippet.js?id=YOUR_SNIPPET_KEY" data-avsb="YOUR_SNIPPET_KEY" async></script>
HTML9 lines

The first <script> is the stub, and it does three jobs:

  • It defines avsb.ready, avsb.on, avsb.consent.set and the four avsb.track.* methods immediately, so a call to any of them anywhere on the page is safely held and replayed, even if it runs before the bundle has loaded. That matters most on an order confirmation page, where avsb.track.purchase(...) often runs before an async bundle has arrived.
  • It starts downloading your experiment settings straight away, in parallel with the bundle, so experiments show up sooner and the page spends less time hidden.
  • Its last line hides the page (opacity: 0 on <html>) before the browser paints anything, and starts a 3 second timer that reveals it again no matter what. This is what makes an async install flicker-free. See Anti-Flicker.

The second <script> loads the bundle asynchronously, so it never blocks your page.

Installed a while ago?

Older copies of this tag keep working exactly as before, nothing breaks and nothing needs to change. But the current tag starts downloading your experiment settings the moment it runs, so experiments start sooner. If you installed before this page showed the download line in the tag, paste the latest copy from Project Settings over your old one when convenient.

To get your real snippet, open Project Settings → Snippet in the A vs B dashboard and click Copy.

The file is tailored to your project

The bundle the loader tag fetches contains only what your experiments use, and grows automatically when you publish something that needs more. The Your snippet card on the Snippet settings tab shows its exact size and what is inside.

Where to place it

Paste both tags inside the <head> of every page where you want experiments to run. The best spot is immediately after the opening <head> tag, before any other scripts or stylesheets:

HTML
<!DOCTYPE html><html lang="en">  <head>    <!-- A vs B snippet: place first in head -->    <script>    window.avsb=window.avsb||{};window.avsb.q=window.avsb.q||[];    window.avsb.ready=window.avsb.ready||function(f){window.avsb.q.push(f)};    window.avsb.on=window.avsb.on||function(n,f){var t=['on',n,f];window.avsb.q.push(t);return function(){t[0]=null}};    window.avsb.consent=window.avsb.consent||{set:function(s){window.avsb.q.push(['consent.set',s])},get:function(){return{}}};    window.avsb.track=window.avsb.track||{};['event','segment','purchase','cart'].forEach(function(m){window.avsb.track[m]=window.avsb.track[m]||function(a,b){window.avsb.q.push(['track.'+m,a,b])}});    (function(){window.avsb._t0=Date.now();window.avsb._df=fetch('https://cdn.avsb.cloud/YOUR_SNIPPET_KEY/datafile.json').catch(function(){});var d=document,e=d.documentElement,s=d.currentScript,a=s&&s.getAttribute('data-avsb-timeout'),t=a==null?3000:+a;if(!(t>0)||window.avsb.version)return;e.style.opacity='0';e.style.pointerEvents='none';window.avsb._t=setTimeout(function(){e.style.removeProperty('opacity');e.style.removeProperty('pointer-events')},t)})();    </script>    <script src="https://cdn.avsb.cloud/snippet.js?id=YOUR_SNIPPET_KEY" data-avsb="YOUR_SNIPPET_KEY" async></script>    <meta charset="UTF-8" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title>My Website</title>    <!-- rest of your head content -->  </head>  <body>    <!-- page content -->  </body></html>
HTML23 lines
Both tags, and the stub first

Order matters. The stub has to run before the browser paints, and before any of your code calls avsb.*. Pasting only the loader tag still runs experiments, but nothing hides the page and above-the-fold changes will flash.

Async, and still no flicker

The loader tag carries async, so the bundle downloads in the background and your page keeps rendering. Two things make that safe:

  • Early avsb.ready(...), avsb.on(...), avsb.consent.set(...) and avsb.track.*(...) calls are queued by the stub and replayed once the bundle is ready.
  • The page is already hidden by the stub, so visitors do not see the original content while the bundle and your config are on the way.
Should I ever remove async? (advanced)

Almost never. Removing async makes the browser download and run the bundle before drawing the rest of the page. The bundle weighs roughly 30 to 37 KB gzipped depending on what your project uses (the Your snippet card in project settings shows your exact number), so on a warm CDN cache that pause is small, but on a cold cache or a weak mobile connection it is a real render-blocking delay for every visitor, including the ones not in any experiment.

The default (async loader plus the stub's pre-paint hide) gives you the same no-flash result without blocking anything, so keep async unless you have a specific reason not to. If you do drop it, keep the stub tag: the queue behaviour and the safety timer still matter.

Don't change data-avsb

data-avsb on the loader tag carries your snippet key, and it is the first thing the bundle looks for.

Your snippet key is public
Your snippet key is a public identifier, not a secret: it sits in the install tag on every page, it can only fetch that project's experiment configuration and send events, and it can never read or change anything in your dashboard. Credentials covers all four A vs B credentials and which one to reach for.

Leave the attribute exactly as it is. The ?id= in the src carries the same key as a fallback, so a tag with only one of the two still works, but the generated snippet ships both on purpose.

Two attributes are yours to edit:

  • data-avsb-timeout on the first tag changes how long the page can stay hidden. See Anti-Flicker.
  • data-avsb-cookie-domain on the loader tag scopes the visitor cookie to a parent domain, so one visitor keeps one identity across www.example.com and shop.example.com. See Shared Visitor Identity.

After you paste it

Save your file and deploy. Then visit any page of your site once in a browser, and open Project Settings → Snippet in A vs B. The status turns green and shows Installed.

Detection is driven by a real page view

Detection is not a crawl of your site. The snippet sends a tiny ping from the visitor's browser the first time it loads, carrying nothing but your snippet key. That means a staging site, an internal site, or a site behind a firewall or a login all report correctly: someone just has to load a page. If your Content Security Policy blocks our hosts the ping cannot leave the browser, and the console will say so. See Verifying Installation.

Was this helpful?