A/B testing sounds complicated, but the basic idea is simple.
You show one group of users version A, another group version B, and then compare which version performs better.
The hard part is not only sending users to two different pages. The hard part is making sure the traffic is labelled properly so the results can be analyzed later.
I’m Matteo Arellano , and I work across technical SEO, analytics, automation, and data analysis. One type of project I enjoy is when a business needs a simple technical solution that also creates better measurement. This article uses a fictional food delivery example inspired by that kind of problem, with all business-specific parameters removed.
The fictional case: one QR code, two menu pages
Let’s say you run a food delivery business. You want to promote a QR code in a physical location, on a flyer, or inside a delivery bag.
But you are not sure which menu page will sell more.
Version A promotes family combo meals. Version B promotes quick lunch options.
Instead of printing two different QR codes, you create one public campaign URL. When someone scans the QR code, a small JavaScript function randomly sends that user to Menu A or Menu B.
| Test element | Example | Why it matters |
|---|---|---|
| Public campaign URL | https://menu-test.example.workers.dev/ | This is the single URL printed on the QR code or shared in a campaign. Users do not need to choose a version manually. |
| Variant A | Family combos menu | This version may test whether larger bundles increase order value. |
| Variant B | Quick lunch menu | This version may test whether faster, simpler options increase conversion rate. |
| Split logic | 50% / 50% | A random split helps compare two experiences with similar traffic conditions. |
| Tracking label | utm_content | The variant name is stored in the URL so analytics can separate performance later. |
This is not a perfect scientific experiment. It is a practical business experiment. The goal is to learn whether one menu experience creates more orders, more checkout starts, or higher average order value.
What is traffic splitting?
Traffic splitting means dividing visitors between two or more destinations.
In this example, the split is simple:
- 50% of users go to Menu A.
- 50% of users go to Menu B.
The user starts with the same URL, but the system redirects them to one of two destinations behind the scenes.
This is useful when the business wants to compare two paths without asking users to choose manually.
Why use one public URL?
One public URL is easier to manage.
If the URL is printed on a QR code, flyer, poster, receipt, packaging, or campaign material, you do not want to reprint everything every time the test changes.
The public URL can stay the same while the routing logic changes behind it.
For example:
https://menu-test.example.workers.dev/ That URL can send users to Menu A today, split traffic tomorrow, or later send everyone to the winning menu after the test ends.
Why use a 302 temporary redirect?
A 302 redirect means the move is temporary.
That matters because an A/B test is not a permanent migration. You are not saying “this URL has permanently moved.” You are saying “for now, send this visitor to one of these test destinations.”
For SEO and analytics, this distinction matters. A permanent redirect is a different signal. A temporary redirect is more appropriate when the routing is part of a test, campaign, or short-term experiment.
The example JavaScript traffic splitter
This type of logic can run in an edge function, serverless function, or worker. The important idea is that the user visits one URL, and the function decides where to send them.
export default {
async fetch(request) {
// Fictional example: one campaign link splits traffic between two menu pages.
const menuA =
"https://example-food.co/menu/family-combos";
const menuB =
"https://example-food.co/menu/quick-lunch";
// Randomly assign each visitor to one variant.
const variant = Math.random() < 0.5 ? "menu_a_family_combos" : "menu_b_quick_lunch";
// Pick the matching destination.
const target = variant === "menu_a_family_combos" ? menuA : menuB;
// Add campaign tracking parameters.
const url = new URL(target);
url.searchParams.set("utm_source", "restaurant_qr");
url.searchParams.set("utm_medium", "qr");
url.searchParams.set("utm_campaign", "menu_ab_test_june");
url.searchParams.set("utm_content", variant);
// 302 = temporary redirect.
// Useful for an experiment because the test is not a permanent URL move.
return Response.redirect(url.toString(), 302);
}
}; The important part is not the exact hosting provider. The important parts are:
- There is one public campaign URL.
- The script randomly chooses a variant.
- The user is redirected to the correct destination.
- UTM parameters are added before the redirect.
- The redirect is temporary, not permanent.
What are UTM parameters?
UTM parameters are tracking labels added to a URL.
They do not usually change the page content. Their job is to help analytics tools understand where traffic came from and which campaign, channel, or variant created the visit.
A URL with UTM parameters can look like this:
https://example-food.co/menu/family-combos?utm_source=restaurant_qr&utm_medium=qr&utm_campaign=menu_ab_test_june&utm_content=menu_a_family_combos In simple terms, UTM parameters answer:
- Where did the visitor come from?
- What type of campaign was it?
- Which campaign was it?
- Which version of the creative, link, or experience did they see?
The main UTM parameters explained
| Parameter | Meaning | Example | Practical note |
|---|---|---|---|
utm_source | Where the traffic comes from | restaurant_qr | Useful for identifying the original source, such as a QR code, newsletter, partner, paid channel, or social platform. |
utm_medium | The type of traffic | qr | Useful for grouping the channel format. Examples can include email, cpc, social, referral, qr, display, or affiliate. |
utm_campaign | The campaign or initiative | menu_ab_test_june | Useful for grouping all traffic related to one business initiative, promotion, test, launch, or seasonal campaign. |
utm_content | The creative, link, or variant | menu_a_family_combos | Useful for distinguishing A/B test variants, buttons, banners, QR placements, or ad versions inside the same campaign. |
utm_term | The keyword or targeting term | lunch_delivery | Usually used for paid search keywords or targeting labels. Not always needed for QR or organic campaign tests. |
For this food delivery test, the most important parameter is
utm_content, because it stores whether the user saw Menu A or Menu B.
Without that label, you may see campaign traffic, but you will not clearly know which variant created the order.
Why UTM naming consistency matters
UTM parameters are useful only when they are consistent.
For example, these three values may look similar to a human:
utm_medium=qr
utm_medium=QR
utm_medium=qrcode But analytics tools may treat them as different values. That creates messy reporting.
A simple naming convention helps. For example:
- Use lowercase.
- Use underscores instead of spaces.
- Keep campaign names short but descriptive.
- Use
utm_contentfor variants. - Do not change names halfway through the test.
What should the business measure?
The test should not stop at page views.
A menu page can get more clicks but fewer orders. Another menu page can get fewer clicks but higher average order value. That is why the business needs to define the success metric before launching the test.
Menu page views
How many users reached Menu A and Menu B? This confirms whether the split is working and traffic is being tagged.
Order conversion rate
Of the users who saw each menu, what percentage completed an order? This is usually the most important metric.
Average order value
Menu A may convert less often but produce higher-value orders. Menu B may convert more often but with smaller baskets.
Checkout starts
If many users view a menu but do not start checkout, the menu may not create enough purchase intent.
Checkout completion
If users start checkout but do not complete it, the issue may be checkout friction rather than menu positioning.
Device and location differences
QR campaigns often behave differently by device, location, time of day, or physical placement.
A practical measurement plan
A simple plan could look like this:
- Create one campaign URL for the QR code.
- Split traffic 50/50 between Menu A and Menu B.
- Add UTM parameters to both destinations.
- Use
utm_contentto label the variant. - Track menu views, checkout starts, orders, and order value.
- Compare conversion rate and revenue per visitor by variant.
- Keep the test stable long enough to collect useful data.
- Send all users to the winning version after the test ends.
Example reporting table
After running the test, the business could compare the variants like this:
| Variant | Users | Checkout starts | Orders | Conversion rate | Average order value | Revenue per visitor |
|---|---|---|---|---|---|---|
| Menu A: Family combos | 1,000 | 260 | 120 | 12.0% | €31.20 | €3.74 |
| Menu B: Quick lunch | 1,000 | 310 | 145 | 14.5% | €22.40 | €3.25 |
In this fictional example, Menu B has a higher conversion rate, but Menu A has higher revenue per visitor because the average order value is stronger.
This is why analytics matters. If the business only looked at conversion rate, it might choose Menu B. If it looked at revenue per visitor, it might choose Menu A.
Common mistakes in this type of test
No UTM consistency
If one campaign uses qr, another uses QR, and another uses qrcode, reporting becomes messy.
Too many variants at once
Testing five different menus with low traffic makes the results harder to trust.
Changing the test during the test
If the menu, prices, design, or tracking changes mid-test, the result becomes harder to interpret.
Measuring clicks but not orders
A variant that gets more clicks is not automatically the better business option.
What makes this valuable for a business?
The value is not only the redirect.
The value is creating a measurable decision.
Before the test, the business may have opinions:
- “Family combos should sell better.”
- “Lunch offers are probably easier to convert.”
- “The QR code traffic probably behaves differently.”
After the test, the business has evidence:
- Which menu got more checkout starts?
- Which menu created more orders?
- Which menu created more revenue per visitor?
- Which menu should the campaign send users to next?
Where technical SEO and analytics meet
This kind of project sits between analytics, technical implementation, and growth.
The code is small, but the thinking matters:
- Use the correct redirect type.
- Keep the public URL stable.
- Label traffic clearly.
- Define the conversion goal before launching.
- Analyze business outcomes, not only clicks.
That is why I see analytics as part of organic growth. Visibility brings users in, but measurement explains what happens next.
How I can help
I help businesses design clearer measurement systems for campaigns, websites, SEO projects, and conversion journeys.
That can include UTM naming conventions, campaign tracking, A/B test setup, redirect logic, analytics audits, conversion event reviews, and data analysis.
The goal is not to track everything. The goal is to track what helps the business make better decisions.
Need help measuring campaigns or conversion journeys?
I can help review your campaign tracking, UTM structure, analytics setup, and conversion paths so you can understand what is actually working.
Request a technical visibility checkThis is not about adding random tracking everywhere. It is about creating clean measurement that supports better business decisions.