Practical notes on testing No growth-hacking fluff Written for small websites Plain language Real examples Useful before impressive
← All posts

A/B Testing for Static Sites (Without a Server or a $200/Month Tool)

Most A/B testing guides assume you've got a server rendering your pages. If your site is plain HTML, built with Hugo or Eleventy, or hosted on Netlify or GitHub Pages, here's how testing actually works.

SplitPea Sun 03 May 2026
A/B THE FIELD

If your website is a collection of HTML files sitting on a CDN somewhere, you've probably noticed that the A/B testing world doesn't really speak to you.

Most guides assume you've got a server rendering pages on the fly. Most tools assume you've got a CMS with plugins. The enterprise tools assume you've got a backend team who can implement server-side testing. And the free options that used to exist (Google Optimize, mainly) are gone.

Static sites are everywhere: marketing sites, portfolio sites, documentation, blogs, landing pages, small business sites built by a developer and handed off. Millions of sites run on Hugo, Eleventy, Jekyll, Astro, or just plain HTML and CSS.

And almost none of the mainstream A/B testing content is written for them.

This piece is.

Why static sites get left out

The short answer: most A/B testing tools were designed for dynamic websites where a server decides what to show each visitor. Static sites don't have that server.

Your pages are pre-built and served directly from a CDN. There's no request-time logic deciding which version of the homepage to show.

That's actually what makes static sites fast and cheap to host. But it also means the standard server-side approach to A/B testing (where the server picks variant A or B before the page loads) doesn't work without adding infrastructure you probably don't want.

The longer answer: the A/B testing industry makes most of its money from enterprise customers with dynamic sites, so that's who the tools are built for. Static site owners are a small, technical, price-sensitive audience. Not exactly a marketer's dream customer.

But the testing problem is the same whether your site is static or dynamic. You've got a headline, a button, a signup form. You want to know if a different version would work better.

The method for answering that question doesn't change. Only the implementation does.

The two approaches that work

Client-side testing (the practical choice)

This is how most static site owners will run A/B tests.

A small JavaScript snippet loads on your page, picks a variant for each visitor, makes the change in the browser, and tracks conversions.

The mechanics: you add a script tag to your site's <head>. When a visitor loads the page, the script checks whether they've been assigned to a variant (usually stored in a cookie or localStorage). If not, it assigns them randomly. Then it modifies the DOM to show the right version. The original page loads first, the script runs, and the change happens.

This is how Google Optimize worked. It's how SplitPea works. It's how most affordable testing tools work.

The flicker question. If you've read anything about client-side A/B testing, you've probably seen warnings about "flicker" or "flash of original content" (FOOC). This is when a visitor briefly sees the original version of your page before the variant loads. The page blinks.

This is a real thing, but it's often overstated.

Flicker matters when:

A lightweight script that changes a headline or a button doesn't produce noticeable flicker on a fast static site. Your pages already load quickly because they're static. A well-built snippet that runs early in the page load makes changes before the visitor even registers them.

If you're changing something above the fold (which you probably are, since that's where the high-impact elements live), the script needs to run before the browser paints that content. Loading it in the <head> with proper priority helps reduce visible flicker. SplitPea’s snippet is under 8KB and loads asynchronously with early execution, but the result still depends on the page, connection, and size of the variant.

Flicker can become more noticeable when a test changes large parts of the layout or when the snippet loads through a tag manager. The risk is lower for a simple headline or CTA change, but preview the experiment on the actual page before launch.

Edge-based testing (the developer option)

If you're hosting on Cloudflare, Netlify, or Vercel, you have access to edge functions (Cloudflare Workers, Netlify Edge Functions, Vercel Edge Middleware). These let you run logic at the CDN level before the page reaches the visitor's browser.

The idea: you maintain two versions of a page (or use an edge function to modify the HTML on the fly), and the edge function randomly assigns each visitor to one version. The visitor never sees a flicker because the correct version is served from the start.

This is closer to server-side testing but without a traditional server. It's the most technically elegant solution for static sites.

The trade-off: you have to build it yourself. There's no visual editor, no dashboard, no statistics engine. You're writing code, managing cookies for consistent assignment, and piping events to an analytics tool to measure results.

If you're already comfortable writing Cloudflare Workers or Netlify functions, this is doable. If you're a freelancer who just wants to test a headline, it's overkill.

It's also platform-specific. Your testing logic is tied to your hosting provider. Move from Netlify to Cloudflare and you're rewriting your testing infrastructure.

For most static site owners, client-side testing with a small snippet is the simpler and more practical path.

What you can test on a static site

Everything you'd test on a dynamic site, as long as it's visible in the HTML. The common ones:

Headlines. The highest-impact, lowest-effort test on any site. Write a second version, let the snippet swap it in for half your visitors. This is where we'd start. If you need ideas, we wrote a guide on what to test when you're not sure where to start.

Call-to-action buttons. The text, the placement, or both. "Get Started" versus "See Pricing" versus "Book a Call." Small change, measurable impact.

Hero sections. Image versus no image. Stock photo versus real photo. Short copy versus long copy.

Form fields. If your static site has a contact form (via Formspree, Netlify Forms, or similar), test reducing the number of fields.

Social proof. Adding a testimonial near the CTA, or a trust line like "Used by 300+ small businesses."

Pricing presentation. If you show pricing on a static marketing site, test how you present it. Two tiers versus three. Leading with the most popular plan versus the cheapest.

What you can't easily test with client-side tools: anything that happens before JavaScript runs (like the very first paint of the page for users on extremely slow connections) or server-side logic (like which URL a visitor gets routed to). For static sites, these limitations rarely matter in practice.

How SplitPea works with static sites

SplitPea was partly built with static sites in mind. The setup is straightforward:

  1. Add the snippet to your site's <head>. One script tag. Works on any site that lets you edit HTML, which every static site does by definition.
  2. Create an experiment in the dashboard. Pick the page and set a goal.
  3. Use the visual editor to make your change. Click the element and type the new version. Or use a CSS selector if you prefer.
  4. Publish. SplitPea handles the traffic splitting, assignment persistence, conversion tracking, and statistical analysis.

The snippet is under 8KB. It does not load jQuery or require a tag manager. Because every script adds some work, check the result on your own site before launching a test.

If you want the step-by-step version, here's a walkthrough of setting up your first test.

Common setups and how to handle them

Plain HTML on shared hosting or a VPS. Add the script tag directly to your HTML files directly. If you've got a shared header file or template, add it once there.

Hugo, Eleventy, Jekyll, or another static site generator. Add the script tag to your base template or layout partial. In Hugo, that's usually layouts/_default/baseof.html. In Eleventy, it's your layout file. In Jekyll, _includes/head.html. One line, and every page on your site has the snippet.

Astro. Add it to your base layout component. Astro renders to static HTML by default, so it works the same as any other static generator.

GitHub Pages. Works fine. Add the snippet to your HTML or Jekyll layout. No special configuration needed.

Netlify or Vercel. Works fine with the client-side snippet approach. If you want to go the edge function route instead, that's an option too, but the snippet approach is simpler.

Webflow (exported or hosted). If you're on Webflow's hosted plan, you can add custom code in the site settings. If you've exported the HTML and are hosting it statically, add the snippet to the exported files.

What about page speed?

This is the question static site owners care about most, and rightly so. You chose a static site because it's fast. You don't want a testing tool to undo that.

The honest answer: any client-side A/B testing tool adds some overhead. The question is how much.

An enterprise tool like VWO or Optimizely loads 100-300KB of JavaScript, often synchronously (blocking page render until they're done), and sometimes add 1-3 seconds to your page load. That's unacceptable on a static site that loads in 400 milliseconds.

SplitPea's snippet is under 8KB. It loads asynchronously.

For comparison, a single analytics tracking script (Google Analytics 4, for instance) is typically 30-50KB. A typical web font file is 20-40KB. The testing snippet is smaller than both.

On a fast static site, the difference is undetectable in Lighthouse scores. We built it that way on purpose.

When testing doesn't make sense on a static site

Same rules as any other site.

If your pages get fewer than 500 visitors a month, formal A/B testing won't give you reliable results in a reasonable timeframe. Fix the obvious stuff first (clear headline, visible CTA, working contact form, decent page speed) and test later when you've got more traffic.

Also: if your static site is documentation (like a docs site built with Docusaurus or MkDocs), A/B testing probably isn't the right tool. Documentation success is measured differently than marketing page success. Save testing for the pages where you're actually trying to get someone to do something.

The short version

Static sites aren't second-class citizens for A/B testing. Client-side testing with a lightweight snippet works well on them - arguably better than on heavy dynamic sites because there's less JavaScript competing for execution time.

Add a snippet. Change a headline. See what happens.

The fact that your site is static doesn't change the process. If anything, it makes the snippet faster.

SplitPea