> ## Documentation Index
> Fetch the complete documentation index at: https://docs.abtestly.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Targeting overview

> How ABTestly decides who sees which variant.

# Targeting

Every experiment defines two things about who sees it:

1. **Locations** — which URLs the test runs on
2. **Audiences** — which visitors are eligible

A visitor sees the test only if **both** match. If either fails, they see the original (no bucket assignment, no MTU consumed).

## Locations

Locations specify URLs. Supported match types:

| Type                  | Example                       | Matches                          |
| --------------------- | ----------------------------- | -------------------------------- |
| **URL**               | `https://example.com/pricing` | Exact URL only                   |
| **URL contains**      | `/pricing`                    | Any URL with this substring      |
| **URL starts with**   | `https://example.com/blog/`   | Any blog post                    |
| **URL ends with**     | `.html`                       | Any HTML page                    |
| **URL matches regex** | `^/products/[0-9]+$`          | Numeric product IDs              |
| **Hostname**          | `app.example.com`             | Subdomain match                  |
| **Query string**      | `utm_source=email`            | Visitor came from a specific UTM |

Multiple conditions combine with OR by default (any match). Switch the conjunction to AND to require all conditions.

## Audiences

Audiences filter visitors. Supported conditions:

| Condition                     | Examples                                                              |
| ----------------------------- | --------------------------------------------------------------------- |
| **Device**                    | mobile, tablet, desktop                                               |
| **Browser**                   | Chrome, Safari, Firefox, Edge, ...                                    |
| **Operating system**          | iOS, Android, macOS, Windows, Linux                                   |
| **Country / region**          | Via Cloudflare geo                                                    |
| **Language**                  | Browser locale (en, en-US, fr, etc.)                                  |
| **New vs returning**          | Has this user been bucketed before?                                   |
| **Referrer**                  | Came from `twitter.com`, `news.ycombinator.com`, etc.                 |
| **UTM parameters**            | `utm_source`, `utm_medium`, `utm_campaign`, `utm_term`, `utm_content` |
| **Cookies**                   | E.g. `logged_in=true`                                                 |
| **Custom attributes**         | Set via JS: `window.abtestly.identify({ plan: 'pro' })`               |
| **Day of week / hour of day** | Time-windowed campaigns                                               |
| **JS condition**              | Arbitrary expression evaluated against the page                       |

Multiple audience conditions combine with AND by default (visitor must match all). Switch to OR per condition group via the conjunction toggle.

## Saved Locations and Audiences

If you run multiple tests targeting the same URLs or the same visitor segment, save the conditions as a reusable **Location** or **Audience** in your site detail page (Locations / Audiences tabs). Then reference them from experiments instead of copy-pasting rules.

Saved Locations and Audiences are **site-scoped** — each site has its own set. This matches the natural mental model: visitor segments and URL patterns are inherent to a property, not your whole org.

## Bucketing

Once a visitor passes targeting, they're bucketed into a variant. Bucketing is:

* **Deterministic** — same visitor + same experiment = same variant, every time
* **Independent across tests** — a user's assignment in test A doesn't influence test B
* **Persistent** — assignment is cached in `localStorage` and persists indefinitely (until they clear browser data or you change the experiment's bucketing salt)

The hash function is MurmurHash3 with a per-experiment salt, the same algorithm used by Optimizely and Adobe Target. Variant weights split visitors proportionally (e.g., 50/50, 33/33/33, or 90/10 for ramps).

## Traffic allocation

The experiment-level **traffic allocation** percentage controls what share of *eligible* visitors enter the test at all. Common patterns:

* **100%** — full launch test
* **10%** — early ramp; only 1 in 10 eligible visitors gets bucketed, the rest see control without being recorded as exposures
* **50%** — half-traffic A/B with statistical significance gates before scaling

Visitors who don't make the allocation cut don't consume an MTU.

## Quick reference

| Scenario                              | Setup                                                               |
| ------------------------------------- | ------------------------------------------------------------------- |
| Test only on pricing page             | Location: URL contains `/pricing`                                   |
| Test only on mobile                   | Audience: device = mobile                                           |
| Test only US visitors                 | Audience: country in \[US]                                          |
| Test only logged-in users             | Audience: cookie `logged_in` = true                                 |
| Test on new visitors only             | Audience: new\_returning = new                                      |
| Test on returning visitors from email | Audience: utm\_source = email AND new\_returning = returning        |
| Ramp test to 10% of traffic           | Experiment-level traffic allocation = 10%                           |
| Test on weekday business hours        | Audience: day\_of\_week in \[mon-fri] AND hour\_of\_day in \[9..17] |
