# Coding assistants

Instructions for an AI coding assistant to add fivebar to a site, from the tag to events.

An assistant working in your site’s code can read its templates, so it puts the tag where every page gets it and adds what your site needs beyond it, such as the status on error pages or an event for each sign-up. It takes one paste from you. The sections below are written for the assistant.

Open your assistant in the project that builds your site, press **Copy instructions** at the top of this page, choose **Copy instructions** in its menu, and paste them in. If your assistant can read the web, this line is enough:

```
Add fivebar analytics to this site, following https://fiveb.ar/docs/coding-assistants.md
```

It asks for anything it can’t work out, such as the domain. Review its changes as you would anyone else’s.

## What you’re adding

fivebar is web analytics without cookies. A site is counted by one script tag, the same on every page, loaded from fiveb.ar. There’s no package to install and no server code. Each link below is to a page with the details, which you can read as Markdown.

The site’s owner adds it to fivebar first, and the domain it was added under goes in the tag’s `data-domain`. If you’re [connected to fivebar over MCP](https://fiveb.ar/docs/mcp.md), `get_site_setup` gives you the site’s tag with its domain filled in. Otherwise, if you can’t tell the domain, ask.

## Add the tag

Put this in the `<head>` of every page, once, with the site’s domain in place of `example.com`:

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

- Add it to the layout, template or theme every page shares. [Platforms](https://fiveb.ar/docs/platforms.md) says where that is for WordPress, Next.js, Astro, Hugo, Vite, Nuxt, SvelteKit, Google Tag Manager and more.
- Keep `async`, `data-domain` and the `src` as written. The script sends to the host it was loaded from, so don’t bundle it or copy it into the project. To serve it from the site’s own domain, set up a proxy as [Proxying](https://fiveb.ar/docs/proxy.md) says, only if the owner asks for one.
- Don’t delay it until the visitor scrolls or clicks, or move it into a web worker such as Partytown. A visitor who leaves first isn’t counted.
- A single-page app needs nothing more: the script counts each page the app moves to. See [Single-page apps](https://fiveb.ar/docs/single-page-apps.md).

## Add what the site needs

Look through the site for each of these, and add the ones that apply.

### Error pages

On each template that answers with an error status, such as a 404 or 500 page, add `data-status` to the tag with the status, such as `data-status="404"`, from the variable the template has for it. Safari needs it to tell errors from ordinary pages. See [Error pages](https://fiveb.ar/docs/error-pages.md#safari-needs-data-status).

### Private paths

Where addresses hold anything private, such as a token in a sign-in link or an account’s name, set `data-path` to the path to count the page under, such as `data-path="/login/:token"`, or `data-path="/:account/*"` for every page under an account. See [`data-path`](https://fiveb.ar/docs/script-attributes.md#data-path).

### Custom properties

Only if the owner wants them: `data-property-` attributes label each page with what its template knows, such as `data-property-author="Ada Lovelace"`. Never anything about the visitor. See [Custom properties](https://fiveb.ar/docs/properties.md).

### Events

Only for actions the owner wants counted, such as a sign-up or a purchase: ask which, if it isn’t clear. Each event is a goal on the dashboard. On anything clicked:

```
<button data-tally="Signup" data-tally-plan="pro">Start</button>
```

Or from code, such as once a form has been accepted:

```
tally('Signup', { plan: 'pro' });
```

[Custom events](https://fiveb.ar/docs/events.md) covers calling it before the script has loaded, and the names and data an event can have. Pageviews, links to other sites and downloads are counted already, and a thank-you page is a goal the owner adds in the site’s settings, with no code: see [Goals](https://fiveb.ar/docs/goals.md).

### Links

If the site’s links lead somewhere that shouldn’t be followed, such as an app’s links to its customers’ own sites, add `data-links="off"` to the tag. See [Outbound links and downloads](https://fiveb.ar/docs/outbound-and-downloads.md).

### Site search

Only if the site has a search of its own and the owner wants it counted. A search page whose address holds the search, such as `/search?q=shoes`, needs no code: the owner adds a rule in the site’s settings. Where the address doesn’t hold it, such as a results page answering a form, add `data-search` to the tag on the results template, with the search as typed, such as `data-search="{{ query }}"`, and leave it out elsewhere. Either way, add `data-search-results` with the number of results shown, such as `data-search-results="{{ count }}"`, so a search that found nothing is marked. See [Site search](https://fiveb.ar/docs/site-search.md).

### Content Security Policy

Look for one wherever the site sets headers or meta tags: framework or server config, middleware, `vercel.json`, `netlify.toml`, a `_headers` file, Helmet, or a `<meta http-equiv="Content-Security-Policy">`. If there is one, allow `https://fiveb.ar` for loading scripts and for connecting, as [Content Security Policy](https://fiveb.ar/docs/install.md#content-security-policy) explains, nonces and `default-src` included.

## Leave these out

`data-local` is for testing the script, and stops a live site being counted properly. Leave `data-api` out too, unless the site serves the script from its own domain at [other paths](https://fiveb.ar/docs/proxy.md#other-paths), when it says where the counts go. Don’t add a second copy of the tag, or a wrapper of your own around it. [Script attributes](https://fiveb.ar/docs/script-attributes.md) lists every attribute.

## Check it works

1. Build the site, and check the tag is in the `<head>` of several kinds of page, once each, with the right `data-domain`.
2. Nothing is sent from `localhost` or a file, so check the deployed site: each page sends a request to `https://fiveb.ar/api/tally`, answered 202. [If nothing is counted](https://fiveb.ar/docs/install.md#if-nothing-is-counted) says what any other answer means.
3. Connected over MCP, call `check_install` once it’s deployed. It reads the home page and says whether the tag is there, whether the Content Security Policy lets it through, and what has been counted, with what to do about anything wrong.
4. Tell the owner what you added and where, including any events, properties and `data-path` patterns, and what’s left for them to do in fivebar, such as adding page goals or search rules.
