Skip to main content
The snippet is a small JavaScript file, about 0.8 KB for the inline loader and about 15 KB for the runtime that loader pulls in, both gzipped. It runs on every page of your site and it does three things: it decides which variant a visitor sees, it applies your variant’s JavaScript and CSS, and it sends an exposure event back to ABTestly.

Where to get it

Open your site in the dashboard and go to Settings → Snippet. Copy from there. The snippet is built from your consent settings, so it needs to come from your site, not from a copy someone had lying around from last month.
Snippet panel with the install code and copy button

Where to put it

The snippet has to be the first script tag in <head>, before anything else that runs JavaScript. That is not a style preference. Two things depend on it:
  1. Flicker. The earlier the snippet runs, the sooner the runtime is fetched and the variant is applied. Run it late and visitors see the original page for a moment before the variant swaps in.
  2. Execution order. Other scripts on your page might read variant changes, a GTM tag looking for a custom dimension, an analytics event that captures the current headline. Those have to fire after the variant is applied.

Anti-flicker is opt-in

The snippet panel has an Add anti-flicker checkbox. It is unchecked by default, and that default is deliberate. Checked, the snippet includes a .abtestly-async-hide { opacity: 0 !important } rule and puts that class on your <html> element at the top of the page. The class comes off once variants apply, or after two seconds, whichever comes first. The page never stays hidden. Unchecked, nothing is hidden. A variant that changes content above the fold can show the original first for a beat, because the runtime is injected as a dynamic <script> and does not block the parser. Why is it off by default? A page-wide hide costs every visitor on every page, including the ones in no experiment. If the config fetch is ever slow, that becomes a visibly empty site. Flicker only shows on the pages a variant actually changes. Tick the box when, and only when, you can see it.
Anti-flicker lives in the snippet you pasted, not in the runtime. An older snippet with the checkbox off will keep behaving that way until you replace it with a freshly copied one.

Do not load through Google Tag Manager

GTM defers script execution until after DOM parsing. By the time GTM fires, the page has painted. Loading ABTestly through GTM produces consistent flicker, anywhere from 200 to 800 ms of original content visible before the variant swaps in. If you only have GTM access, ask for direct HTML access from whoever owns the site. There is no GTM workaround that does not slow things down.

Do not use async or defer

Both delay execution. The inline snippet needs to run synchronously and as early as it can. It is what decides the variant, and, with anti-flicker on, what puts the hide in place before the first paint. The snippet is already stripped to the minimum work needed; the runtime itself is asynchronous where it can be.

CMS-specific install

WordPress

Use the Insert Headers and Footers plugin, or edit your theme’s header.php. Paste into “Scripts in Header”, above every other script.

Shopify

Theme → Edit code → theme.liquid → find <head> → paste immediately after the opening tag, before any other <script> or {{ content_for_header }} call.

Webflow

Project Settings → Custom Code → Head Code → paste at the very top. Webflow inserts other scripts dynamically; verify the load order on the published site.

Framer

Site Settings → General → Custom Code → Head start → paste the snippet.

Next.js

next/script with strategy="beforeInteractive" inside the root <Head> of _document.tsx. Verify the build output places the tag before any other JavaScript in <head>.

Astro / SvelteKit / Nuxt

Root layout’s <head> slot. Astro: <Fragment slot="head">. SvelteKit: app.html. Nuxt: nuxt.config.tsapp.head.script with tagPosition: "head" and no defer.

Verifying the install

The verify install page has a full checklist. The short version:
If DevTools prints an object with your site id and a version, you are in. If it prints undefined, the snippet did not load, read the verify page for what to check next.

Multiple domains

Each site in your dashboard has its own snippet. If you run acme.com, app.acme.com, and acme.co.uk, add each as its own site and install the matching snippet on each. Snippets are keyed to the domain they were generated for; a snippet from site A running on site B does not decide any variants.

Cache headers

The snippet is served with:
  • Cache-Control: public, max-age=60, s-maxage=300, stale-while-revalidate=86400
  • Cloudflare edge caches for five minutes; browsers cache for one minute.
  • After publishing a new config the snippet picks it up within about sixty seconds worldwide.
If you are testing changes and want to bypass the cache, append ?v=... to the snippet URL in the DevTools Network tab.