# Optional tracker modules

> Load optional tracker modules for time on page and scroll depth, automatic outbound link, download, form and 404 events, Web Vitals and aggregate click maps.

Modules are small separate files the tracker loads on demand, from the same
origin as the tracker (or [`data-api`](/docs/tracker/attributes)). Choose
them with `data-modules`:

```html
<script defer src="https://privatusanalytics.com/js/pa.js" data-site="pa_YOURSITEID"
        data-modules="engage,auto,vitals"></script>
```

| Module | Default | What it adds |
|---|---|---|
| `engage` | On | Time on page (visible time only) and scroll depth |
| `auto` | Off | Outbound links, file downloads, `mailto:`/`tel:` links, form submits and 404s as events |
| `vitals` | Off | Web Vitals: LCP, INP, CLS, FCP, TTFB |
| `clicks` | Off | Aggregate click counts per element for click maps |

> **Warning:** `data-modules` replaces the default. `data-modules="auto"`
> turns `engage` off. Write `data-modules="engage,auto"` to keep both.

## `engage`: time on page and scroll depth

Built into `pa.js` (no extra file). It measures:

- **Engaged time**: only while the tab is visible. Switching tabs or
  minimizing pauses the clock.
- **Scroll depth**: the deepest point reached, as a percentage of the
  scrollable height, stored in 10% bands.

It sends an `engagement` hit when the page is hidden or closed, and before
the next SPA pageview, if at least one second of visible time has passed.
Engagement hits aren't pageviews or events: they don't count toward your
[usage](/docs/billing/usage).

Without `engage`, time on page, visit duration and the "under 10 seconds"
part of [bounce rate](/docs/metrics) can't be measured.

## `auto`: automatic events

Loads `pa.auto.js` and tracks these events:

| Event name | When | Properties |
|---|---|---|
| `Outbound Link` | A click on a link to another host | `domain` (without `www.`), `url` (origin and path, no query) |
| `File Download` | A click on a link to a file (pdf, zip, dmg, exe, csv, xlsx, docx, pptx, mp3, mp4, iso, json, svg and more) | `file` (file name), `host` |
| `Email Link` | A click on a `mailto:` link | `to_domain` (the part after `@`, never the address) |
| `Phone Link` | A click on a `tel:` link | none (the number isn't sent) |
| `Form Submit` | Any form is submitted | `form`: the form's `id`, `name` or `action` |
| `404` | The page's `<title>` contains "404" or "not found", or the page has `<meta name="privatus-404">` | `path` |

Elements with a [`data-privatus-event`](/docs/events/html-attributes)
attribute are skipped by `auto`, so you never count one click twice.

For a reliable 404 event on pages whose title doesn't say "not found",
add the meta tag to your 404 template:

```html
<meta name="privatus-404" content="true">
```

Create [goals](/docs/features/goals) of type *Outbound click* or *File
download* to turn these into conversions.

## `vitals`: Web Vitals

Loads `pa.vitals.js`, which uses `PerformanceObserver` to measure:

| Metric | Unit |
|---|---|
| `LCP` Largest Contentful Paint | milliseconds |
| `INP` Interaction to Next Paint (the slowest interaction) | milliseconds |
| `CLS` Cumulative Layout Shift | unitless, 3 decimals |
| `FCP` First Contentful Paint | milliseconds |
| `TTFB` Time to First Byte | milliseconds |

Values are sent once, when the page is first hidden. Web Vitals hits are
**sampled** on the server at the site's sample rate (**Site settings →
Tracking**, where the Free plan allows up to 10%) and **never count toward
usage**. Results are on the [Performance](/docs/features/performance) page.

## `clicks`: click maps

Loads `pa.clicks.js`, which counts clicks per element for aggregate
[click maps](/docs/features/click-maps). For each click it sends a short CSS
selector (up to 4 levels, e.g. `nav.main > a#pricing`) of the nearest link,
button, input, label, `summary`, `[role=button]` or element with
`data-privatus-click`. Ids and classes with three or more digits in a row
(usually generated) are left out.

It never sends mouse movement, coordinates, the text of the element or
anything typed. Clicks are throttled to one per 300 ms.

Click hits don't count toward your usage.
