> ## 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

> Locations decide which pages count. Audiences decide which visitors count. Activation triggers decide when the exposure fires. Three separate questions.

Targeting in ABTestly is three separate questions.

<CardGroup cols={3}>
  <Card title="Where does it run" icon="location-dot" href="/targeting/url-rules">
    URL rules. Applies to the page.
  </Card>

  <Card title="Who sees it" icon="user-group" href="/targeting/audiences">
    Visitor rules. Applies to the person.
  </Card>

  <Card title="When does it fire" icon="bolt" href="/targeting/activation-triggers">
    On load, on click, when visible, or manual.
  </Card>
</CardGroup>

An experiment includes a visitor when **all three** match. Pages that do
not match a Location are silently skipped. Visitors who do not match an
Audience are silently skipped. If the Activation trigger is On click and
they never click, the exposure never fires.

## Where it runs (Locations)

A Location is a set of **URL rules**. The visitor's current URL is tested
against them. A rule can match on:

* Full URL, hostname, path, or query string, with `equals`, `contains`,
  `starts with`, `ends with`, or `regex`, plus their negations.
* **Case sensitivity is per-rule.** New URL rules default to
  case-insensitive. See [URL rules](/targeting/url-rules) for the details
  and the migration story.

You can define rules inline on an experiment, or you can save a Location
once and attach it to many experiments. Saved locations live under **Site →
Locations** and are the right pick as soon as you have more than one test
on the same set of pages.

## Who sees it (Audiences)

An Audience is a set of **visitor rules**. Rules can match on:

* **Device**, **browser**, **operating system**.
* **Geo**, country from a curated list, plus region and city (both
  case-insensitive text).
* **Language** the browser prefers.
* **Visitor history**, new vs returning, visit count, days since last
  visit, pages viewed this session, whether they have completed a specific
  goal already.
* **Traffic source**, referrer, and UTM source, medium, campaign, term,
  content.
* **Time of day** and **day of week** in the site's project timezone.
* **Cookie value** or a custom **JavaScript condition** you write.

Like Locations, an Audience can be inline or saved. Saved audiences live
under **Site → Audiences**.

## When it fires (Activation)

Activation decides the moment the exposure event fires and the variant
applies. That timing matters for two reasons: it is the number that lands
in your funnel, and it is the point at which the variant's JavaScript runs.

The modes are:

* **On load** (default), fires immediately as soon as the page's other
  targeting rules match.
* **On click**, waits for a click on a CSS selector, then fires.
* **When visible**, waits until an element is at least 1 % on-screen,
  then fires.
* **Manual**, waits for your own code to call
  `abtestly.activate("your-key")`.

If you have never picked a non-default mode, you have been using **On load**.
See [Activation triggers](/targeting/activation-triggers) for when to reach
for the others.

## Mutual exclusion groups

Two experiments that touch the same button in different ways would be a
mess if a visitor could enter both at once. **[Exclusion
groups](/targeting/exclusion-groups)** solve that. Members of a group are
partitioned so that any visitor can enter at most one. This has to be
opt-in per experiment; ABTestly will never quietly bucket one of your
tests out of another.

## The mental picture

```mermaid theme={null}
%%{init: {'theme':'base', 'themeVariables': {
  'fontSize': '17px',
  'fontFamily': 'ui-sans-serif, system-ui, sans-serif',
  'primaryTextColor': '#0f172a',
  'lineColor': '#94a3b8'
}, 'flowchart': {'nodeSpacing': 45, 'rankSpacing': 70, 'padding': 16}}}%%
flowchart LR
  P["<b>Visitor loads<br/>a page</b>"]
  L{"Location<br/>matches?"}
  A{"Audience<br/>matches?"}
  X{"Not blocked<br/>by exclusion<br/>group?"}
  T{"Activation<br/>trigger<br/>fires?"}
  E["<b>Exposure event<br/>+ variant applied</b>"]

  P --> L
  L -- yes --> A
  L -- no  --> Skip1["skipped, silently"]
  A -- yes --> X
  A -- no  --> Skip2["skipped, silently"]
  X -- yes --> T
  X -- no  --> Skip3["skipped, silently"]
  T -- fires --> E
  T -- never --> Skip4["skipped"]

  classDef entry   fill:#dbeafe,stroke:#2563eb,stroke-width:2px,color:#0f172a;
  classDef check   fill:#fef3c7,stroke:#d97706,stroke-width:2px,color:#0f172a;
  classDef fire    fill:#dcfce7,stroke:#16a34a,stroke-width:2.5px,color:#0f172a;
  classDef skip    fill:#fee2e2,stroke:#dc2626,stroke-width:1.5px,color:#7f1d1d,stroke-dasharray: 4 3;

  class P entry
  class L,A,X,T check
  class E fire
  class Skip1,Skip2,Skip3,Skip4 skip

  linkStyle 7 stroke:#16a34a,stroke-width:2px;
  linkStyle 1,3,5 stroke:#16a34a;
  linkStyle 2,4,6,8 stroke:#dc2626,stroke-dasharray: 4 3;
```

If your experiment never seems to fire, walk that diagram. Nine times out
of ten the answer is one of the first three diamonds.
