# Configuration

URL: https://supapulse.app/docs/core/configuration

Every option init() accepts in @supapulse/core, with defaults, and how to set them per environment.

```ts
supapulse.init({
  apiToken: 'pub_your_token', // required
  endpoint: 'https://supapulse.app/api/ingest',
  fingerprintEndpoint: 'https://supapulse.app/api/fingerprint',
  autoPageviews: true,
  debug: false,
  maxRetries: 10,
  retryBackoff: 1000,
  autoOutbound: false,
  autoDownloads: false,
  autoForms: false,
  engagement: false,
});
```

These are all the options. The values shown are the defaults.

| Option | Type | Default | What it does |
| --- | --- | --- | --- |
| `apiToken` | `string` | none | The site's public token. Required. |
| `endpoint` | `string` | `https://supapulse.app/api/ingest` | Where events are sent. |
| `fingerprintEndpoint` | `string` | `endpoint` with `/ingest` replaced by `/fingerprint` | Where `getVisitorFingerprint()` asks for the visitor fingerprint. |
| `autoPageviews` | `boolean` | `true` | Send a pageview on init and on every History API navigation. |
| `debug` | `boolean` | `false` | Log initialization, sends, retries and drops to the console with a `[Supapulse]` prefix. |
| `maxRetries` | `number` | `10` | Attempts per event before it's dropped. |
| `retryBackoff` | `number` | `1000` | Base delay in milliseconds. It doubles after each failed attempt, up to 30 seconds. |
| `autoOutbound` | `boolean` | `false` | Send `Outbound Link: Click` for clicks on links to other hosts. See [Automatic events](https://supapulse.app/docs/core/auto-tracking). |
| `autoDownloads` | `boolean \| string[]` | `false` | Send `File Download` for links to files. A list replaces the default extensions. |
| `autoForms` | `boolean` | `false` | Send `Form: Submission` for form submits, without field values. |
| `engagement` | `boolean` | `false` | Measure scroll depth and time on page. See [Automatic events](https://supapulse.app/docs/core/auto-tracking#scroll-depth-and-time-on-page). |

## apiToken [#apitoken]

The public token from the site's settings. It starts with `pub_`. Never put the secret token (`sec_…`) in browser code.

## endpoint [#endpoint]

Leave it unset unless you proxy requests through your own domain. A proxy must:

- forward the request body unchanged, including its `text/plain` content type (that's how `sendBeacon` sends JSON);
- pass the visitor's IP address in `X-Forwarded-For` and keep the `User-Agent` header, because the visitor hash and the country come from them;
- keep the `Origin` header, or send one that matches the site's domain.

## autoPageviews [#autopageviews]

With `true`, the tracker sends a pageview when it initializes and patches `history.pushState` and `history.replaceState` and listens to `popstate` to send one per navigation. With `false`, nothing is sent until you call `pageview()`. See [SPA support](https://supapulse.app/docs/core/spa-support).

## debug [#debug]

```ts
supapulse.init({ apiToken: 'pub_your_token', debug: true });
```

Logs lines like `[Supapulse] Initialized`, `[Supapulse] Event sent`, `[Supapulse] Send failed` and `[Supapulse] Dropped after 10 attempts`. Turn it off in production.

## maxRetries and retryBackoff [#maxretries-and-retrybackoff]

The tracker sends with `navigator.sendBeacon` first. If the browser queues the beacon, the send counts as done. If not, it uses `fetch`. A failed `fetch` is retried after `retryBackoff × 2^(attempt − 1)` milliseconds, capped at 30 seconds. A `429` waits for the `Retry-After` header instead. After `maxRetries` attempts the event is dropped.

Pending retries live in memory. When the page is hidden or closed, the tracker tries to send them once more.

## Script tag options [#script-tag-options]

The script tag reads `data-token`, `data-endpoint`, `data-debug="true"` and `data-auto`, a comma list of `outbound`, `downloads`, `forms` and `engagement`. The other options keep their defaults. For anything else, install from npm.

## Per environment [#per-environment]

Read the token from your build's environment so development and production can use different sites:

```ts
supapulse.init({
  apiToken: import.meta.env.VITE_SUPAPULSE_TOKEN,
  debug: import.meta.env.DEV,
});
```

| Tool | Variable must start with |
| --- | --- |
| Vite | `VITE_` |
| Next.js | `NEXT_PUBLIC_` |
| Create React App | `REACT_APP_` |

To skip tracking in development, don't call `init()` when the token is missing:

```ts
const token = import.meta.env.VITE_SUPAPULSE_TOKEN;
if (token) {
  supapulse.init({ apiToken: token });
}
```

Calls to `pageview()` and `event()` on an uninitialized tracker log `[Supapulse] Not initialized` and do nothing.
