LinkBit
How to A/B Test Two Landing Pages Using Campaign Links

Oct 13, 2026

How to A/B Test Two Landing Pages Using Campaign Links

How to A/B Test Two Landing Pages Using Campaign Links

You have two landing pages and one campaign link. You want to know which page converts better without sending half your traffic to a page you haven't tested. The usual answer is an A/B test, but the mechanics of routing a single campaign link to two destinations and then measuring the result are less obvious.

This article covers a practical setup: a stable campaign URL that redirects visitors to variant A or B, assigns each visitor consistently, and passes the variant through to your analytics. The code is small; the discipline is in consistent assignment and clean measurement.

The routing problem

A campaign link is the URL you put in ads, emails, social posts, or QR codes. If you change that URL for every experiment, you lose attribution and break links that people have already shared. So the campaign link should stay stable, and the decision about which landing page to show should happen behind it.

The simplest architecture:

  1. Campaign link (short or long) points to a redirect endpoint, e.g. https://example.com/campaign.
  2. The redirect endpoint assigns a variant and sends a 302 to the matching landing page.
  3. The landing page records the variant and reports conversions.

This keeps one public URL while you test behind the scenes.

Assignment: random once, then sticky

The most common mistake is assigning a variant on every page load. If the same visitor sees page A, then page B on refresh, your data is noisy and the user experience is confusing.

You want sticky assignment: once a visitor is assigned to A or B, they see that variant for the duration of the test. A first-party cookie is the simplest way to do this.

On first visit, pick a variant at random and set a cookie. On later visits, read the cookie and use the same variant.

const LANDING_PAGES = {
  a: 'https://example.com/landing-a',
  b: 'https://example.com/landing-b',
};

function getVariant(request) {
  const cookieHeader = request.headers.get('Cookie') || '';
  const match = cookieHeader.match(/ab_variant=(a|b)/);
  if (match) return match[1];
  return Math.random() < 0.5 ? 'a' : 'b';
}

export default {
  async fetch(request) {
    const url = new URL(request.url);
    if (url.pathname !== '/campaign') {
      return new Response('Not found', { status: 404 });
    }

    const variant = getVariant(request);
    const destination = new URL(LANDING_PAGES[variant]);
    destination.searchParams.set('variant', variant);

    const response = Response.redirect(destination.toString(), 302);
    response.headers.set('Cache-Control', 'no-store');

    const existingCookie = request.headers.get('Cookie') || '';
    if (!existingCookie.includes('ab_variant=')) {
      response.headers.append(
        'Set-Cookie',
        `ab_variant=${variant}; Path=/; Max-Age=2592000; SameSite=Lax`
      );
    }

    return response;
  },
};

A few details matter here:

  • 302 (temporary) instead of 301 (permanent) so browsers and proxies do not cache the redirect permanently.
  • Cache-Control: no-store on the redirect response so a CDN does not serve the same variant to everyone.
  • Appending ?variant= to the destination makes the variant available to client-side analytics without reading cookies.

If you use cookies, check your privacy requirements. A first-party, non-tracking cookie that only stores a or b is usually fine, but it should be covered by your cookie policy. If you cannot use cookies, a fallback is hashing a combination of IP and user agent, but that is less stable and can misassign visitors on shared networks.

Passing the variant to analytics

The A/B test is only as good as its measurement. You need to know which variant each conversion belongs to.

The easiest approach is to read the variant query parameter on the landing page and send it to your analytics tool as a custom dimension or event property.

const params = new URLSearchParams(window.location.search);
const variant = params.get('variant') || 'unknown';

analytics.track('Landing Page View', { variant });

analytics.track('Signup', { variant });

If you use Google Analytics 4, set the variant as a user property or include it in the event parameters. In Plausible or Fathom, you can pass it as a custom property. The exact API depends on your tool, but the idea is the same: every event tied to the experiment carries the variant.

Do not rely on URL parameters alone if users can navigate away and come back. Either set the cookie on the redirect (as above) or set a cookie on the landing page from the query parameter, so the variant persists across page views.

Common pitfalls

Client-side redirects cause flicker. If you assign the variant with JavaScript after the page loads, the visitor may briefly see the wrong page. Server-side or edge redirects happen before any HTML is rendered.

Bots skew the results. Crawlers and monitoring tools often follow redirects. You can exclude known bot user agents from assignment, or simply filter them out in analytics. Either way, know that your raw traffic numbers include non-humans.

Stopping too early. A/B tests need enough conversions to distinguish a real difference from noise. If you have low traffic, you may need to run the test for weeks. Use a sample size calculator before you start, and don't peek at the results every hour.

Testing during a seasonality spike. If you run variant A during a sale and variant B after it, you are measuring time, not the landing page. Run both variants simultaneously.

Forgetting `noindex`. Landing pages used in a test should have <meta name="robots" content="noindex"> so search engines don't index two near-duplicate pages. The redirect endpoint should also not be indexed.

Keeping the campaign link shareable

A redirect endpoint like https://example.com/campaign is fine, but it may be long, especially if you add tracking parameters. A short link can make the campaign URL easier to paste into ads, social bios, or QR codes.

You can point a short link at your assignment endpoint. For example, a short link service like LinkBit can give you a compact URL that redirects to https://example.com/campaign. The edge function still handles variant assignment; the short link just makes the entry point cleaner to share.

One caution: if a short link service offers its own A/B or split-testing feature, don't layer it on top of your own assignment logic unless you have verified how the two interact. Duplicate splitting can break sticky assignment and make the data harder to interpret. Keep the experiment logic in one place.

What to measure

For each variant, track:

  • Visitors assigned: how many people entered the test.
  • Conversions: the action you care about (signup, purchase, demo request).
  • Conversion rate: conversions divided by visitors.
  • Time to conversion: useful if the decision is not immediate.

Compare conversion rates, but also check whether the variants differ in bounce rate, scroll depth, or other engagement signals. A page that converts slightly better but has a much higher bounce rate may not be the winner you think it is.

Wrapping up

A/B testing two landing pages with one campaign link comes down to three things:

  1. A stable campaign URL that redirects to the variant.
  2. Sticky, random assignment stored in a cookie.
  3. Clean analytics that carry the variant through to conversion.

The code is a few dozen lines. The harder part is resisting the urge to change the test midway, and making sure your measurement is as reliable as your routing.

#ABTesting #WebDevelopment #EdgeComputing #Analytics #LandingPages