# Snippet

The tracking snippet is a one-line script tag:

```html
<script
  defer
  data-domain="example.com"
  src="https://yoursite.com/sleek-track-3f2a9c1b7d4e.js"
></script>
```

`data-domain` names the tracked site and `src` points at the tracker, which
the WordPress install running SleekTrack serves. The twelve characters after
`sleek-track-` are a hash of the tracker's contents, so your snippet shows a
different value. The tracker works out its collection endpoints from its own
address.

## Installing the snippet

Copy the snippet from the **Snippet** tab of the site's settings, or print it
with `wp sleek track sites script <id>`, and paste it into the `<head>` of
the site you want to track. On a WordPress site, a header scripts option in
your theme or a plugin such as SleekByte works well.

The install that tracks itself needs no snippet: SleekTrack prints the
tracker's settings in its pages' head and loads the same hashed file with
`defer`, and keeps it current.

Because the file name carries the content hash, browsers and CDNs can cache
the tracker for a long time. An update that changes the tracker also changes
the file name, so after updating, copy the snippet from the site settings
again on every external site. Earlier file names keep serving the current
tracker in the meantime.

The tracker records one pageview each time a page loads. Navigation that
changes the page without a reload, as in a single-page application, is not
recorded as a pageview.

## What it collects

- The page URL and referrer
- The page title, sent with each pageview
- UTM parameters (`utm_source`, `utm_medium`, `utm_campaign`, `utm_content`,
  `utm_term`) when the URL has them
- How far the visitor scrolled, sent once as an engagement event when the
  page is hidden or closed
- Outbound link clicks and file downloads, as described in
  [Events and goals](/docs/track/events.md#automatic-events)

Device type, browser and operating system are derived from the user agent at
collection time; the country and location come from request headers or the
optional city database. The collector stores page titles and scroll depth
only while **Page titles** and **Scroll depth** are on in the
[collection settings](/docs/track/configuration.md); both are on by default.

The snippet sets no cookies and stores no identifier in the browser.

## How it sends data

Events are sent with `fetch` requests marked `keepalive`, which never block
rendering or navigation, so a pageview is recorded even when the visitor
leaves at once. Browsers without `fetch` use `sendBeacon`. If the primary
collection endpoint fails or does not answer within five seconds, for example
behind an overzealous firewall, the tracker retries through a fallback
endpoint on `admin-ajax.php` and remembers which one worked. That choice is
the only thing kept in the browser, and it is the same for every visitor.

## What gets dropped

The collector discards:

- Requests from visitors whose browser sends the `DNT: 1` header
- Requests from known bots, crawlers and script clients, or with no user agent
- Events for unknown domains or inactive sites
- Requests from **Excluded IP addresses**
- Traffic referred by a built-in list of referrer-spam domains or by your
  **Blocked referrers**
- Scroll depth events while **Scroll depth** is off
- Requests over the per-minute rate limit

**Excluded roles** works differently: the install that tracks itself does not
print the tracker for logged-in users with those roles, so their visits are
never sent. Snippets on external sites are not affected.

Collector responses carry an `X-SleekTrack-Outcome` header with one of these
values:

| Outcome                | Meaning                                                                |
| ---------------------- | ---------------------------------------------------------------------- |
| `accepted`             | The event was stored                                                   |
| `ignored_dnt`          | The browser sent `DNT: 1`                                              |
| `ignored_bot`          | The user agent is a bot or empty                                       |
| `ignored_excluded`     | The visitor's IP address is excluded                                   |
| `ignored_spam`         | The referrer is on the spam or blocked list                            |
| `ignored_engagement`   | Scroll depth collection is off                                         |
| `unknown_site`         | The domain is not tracked or the site is inactive                      |
| `rate_limited`         | Too many requests from this address (HTTP 429)                         |
| `invalid_payload`      | The request body is missing, malformed or over 10 KB (HTTP 400 or 413) |
| `invalid_method`       | The request was not a `POST` (HTTP 405)                                |
| `ready`                | The answer to a CORS preflight `OPTIONS` request                       |
| `invalid_health_token` | An installation check carried a wrong token (HTTP 403)                 |
| `error`                | The collector failed (HTTP 500)                                        |

## Checking the installation

A site's dashboard shows **No events received** until its first event
arrives, with one of these states:

- The tracking script is installed and the collector is waiting for traffic
- The tracking script was not found on the site's public home page
- The site's public home page could not be reached
- The external tracking script has not been checked yet
- The collector file is missing from this installation

**Check installation** fetches `https://<domain>/` and looks for a SleekTrack
script tag whose `data-domain` matches the site. It then sends a test event
through the collector with the site's private token, which skips the Do Not
Track, bot, excluded IP and referrer checks, and reports whether the event was
accepted, stored and removed again. A failed test names the collector's
outcome from the table above.

If the snippet is not found, purge the page and CDN caches and check the
clean, logged-out HTML of the home page. The install that tracks itself always
counts as installed.
