# Getting started

Add your site, paste one script tag into every page, and fivebar starts counting.

The tag is one line, the same on every page, so on most sites it goes in the template they all share, and nothing runs on your server. From the first visit, the dashboard shows which pages are read, where visitors came from and how fast the site loads for them.

## Add the site

Sign in, open [Sites](https://fiveb.ar/sites), and type your domain under Add a site, such as `example.com`. A whole address works too: fivebar keeps the domain and drops any `www.`, so `example.com` and `www.example.com` are one site.

A new site counts its days in the time zone your account’s [Settings](https://fiveb.ar/settings) choose for new sites, UTC until you pick another. You can change it in the site’s own settings.

### Subdomains

A site covers its domain and every subdomain, so `example.com`, `www.example.com` and `shop.example.com` are counted together, by path: each one’s home page is `/`. To count a subdomain on its own, add it as a site of its own and use that site’s tag there.

## Add the script

Paste this into the `<head>` of every page you want counted, with your domain in place of `example.com`:

```
<script async data-domain="example.com" src="https://fiveb.ar/js/tally.js"></script>
```

The site’s settings give you the tag with your domain filled in, and so does its dashboard until the first visit arrives. Put it in the template or theme every page shares: [Platforms](https://fiveb.ar/docs/platforms.md) shows where that is on WordPress, Next.js, Shopify, Google Tag Manager and more. Or let a coding assistant do it: [Coding assistants](https://fiveb.ar/docs/coding-assistants.md) has instructions to paste into one. To serve the script from your own domain, so content blockers that know fiveb.ar let it through, see [Proxying](https://fiveb.ar/docs/proxy.md).

- `async` lets the page keep loading while the script arrives. The page is counted as soon as the script runs, so a visitor who leaves before the page has finished loading still counts.
- `data-domain` is the site the page is counted under. [Script attributes](https://fiveb.ar/docs/script-attributes.md) covers it and the rest.

The script sets no cookies and stores nothing in the visitor’s browser. One tag per page is enough: a page that ends up with two, one in its template and one from a tag manager, say, is still counted once.

## Check it works

Open a page of your site, then its dashboard. You’ll be among those on the site now straight away, and in the rest of the figures within a minute or two. Until the first visit arrives, the dashboard shows the tag in place of figures, and switches to them by itself when one does. A site added in the last few minutes can take up to six minutes more to start counting.

An app you’ve [connected over MCP](https://fiveb.ar/docs/mcp.md) can check for you: ask it whether fivebar is working on your site. It reads your home page for the tag and its policy, as the [installation checker](https://fiveb.ar/docs/install/checker.md) does, and says what fivebar has counted so far.

### If nothing is counted

Type your domain into the [installation checker](https://fiveb.ar/docs/install/checker.md). It reads your home page and says whether the tag is on it, whether the tag counts for a site the page is on, and whether a [Content Security Policy](https://fiveb.ar/docs/install.md#content-security-policy) stops it, with what to change. If it finds nothing wrong, it’s usually one of these:

- **Your browser.** A content blocker or privacy setting can stop the script. Visit from another browser, or your phone.
- **Your visits are excluded.** A site that excludes your address or network never counts you. See [Excluding traffic](https://fiveb.ar/docs/excluding-traffic.md).
- **A copy on your own computer.** A page on `localhost`, on `127.0.0.1` or opened from a file never sends anything.
- **A check by script.** A page fetched by `curl` or a script runs none of its JavaScript, so it sends nothing and shows nowhere. A browser a script drives, headless or not, or code that sends counts to `/api/tally` itself, is taken for a bot’s, so it’s on the site’s [Bots](https://fiveb.ar/docs/bots.md) page, not among its visitors.
- **A VPN or a cloud server.** A visit through most VPNs, or from a server in the cloud, comes from a hosting network, so it’s taken for a bot’s and is on the Bots page too. While nothing else is counted, the dashboard says beside the tag how many pageviews were.
- **The `data-domain`.** Check its spelling against the site’s settings, which the checker can’t see.

If you use your browser’s developer tools, the Network panel shows the page’s request to `/api/tally` and its answer: 202 when it arrived, though a bot or an excluded visit gets that too, 403 when the page isn’t on the site’s domain or under it, and 404 when no site has that `data-domain`.

## Content Security Policy

If your site sends a Content Security Policy, in a `Content-Security-Policy` header or a `<meta http-equiv="Content-Security-Policy">` tag, it has to let the script load from fiveb.ar and send its counts back there. The [installation checker](https://fiveb.ar/docs/install/checker.md) reads your site’s policy and says whether it does, and what to change if not. Through a [proxy](https://fiveb.ar/docs/proxy.md), `'self'` is enough.

Add `https://fiveb.ar` to two directives:

- `script-src`, so the script can load. If the policy has `script-src-elem`, that decides instead, so add it there.
- `connect-src`, so the script can send. It uses `navigator.sendBeacon()`, falling back to `fetch()`, and `connect-src` governs both.

```
script-src 'self' https://fiveb.ar; connect-src 'self' https://fiveb.ar
```

The script runs no inline code and evaluates no strings, so it needs neither `'unsafe-inline'` nor `'unsafe-eval'`. A `Content-Security-Policy-Report-Only` header blocks nothing but reports what it would, so allow fiveb.ar there too before you enforce it.

### Policies that rely on default-src

A policy without one of those directives falls back to `default-src`. Don’t add fiveb.ar there: it would let fiveb.ar in for images, frames and everything else `default-src` covers. Add the two directives instead, each with what `default-src` allows plus fiveb.ar:

```
default-src 'self'; script-src 'self' https://fiveb.ar; connect-src 'self' https://fiveb.ar
```

### Nonces and strict-dynamic

With `'strict-dynamic'` in `script-src`, the browser ignores the addresses listed there and loads only scripts whose tag carries the page’s nonce. Give the tag the same `nonce` your server gives the page’s other scripts, fresh for each page:

```
<script async nonce="…" data-domain="example.com" src="https://fiveb.ar/js/tally.js"></script>
```

A tag added by a tag manager needs no nonce of its own, since `'strict-dynamic'` trusts the scripts a trusted script adds. `connect-src` still needs fiveb.ar.

## What it counts

With nothing more to set up, the script counts:

- every pageview, including each page of a [single-page app](https://fiveb.ar/docs/single-page-apps.md)
- clicks on links to other sites and to files, as [outbound clicks and downloads](https://fiveb.ar/docs/outbound-and-downloads.md)
- how fast each page loaded, as [page speed](https://fiveb.ar/docs/speed.md)
- how long each page was on screen and how far down it was read, as [engagement](https://fiveb.ar/docs/engagement.md)

To count more, send [custom events](https://fiveb.ar/docs/events.md), set up [goals](https://fiveb.ar/docs/goals.md), count what visitors search your site for with [site search](https://fiveb.ar/docs/site-search.md), or label pages with [custom properties](https://fiveb.ar/docs/properties.md).
