# Overview

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

@supapulse/core is the framework-agnostic browser tracker: automatic pageviews, custom events, SPA navigation and retries.

`@supapulse/core` is the browser tracker behind every Supapulse install. The script tag loads it from jsDelivr; apps can install it from npm. It has no runtime dependencies, and the browser build is about 2.3 KB gzipped.

## What it does [#what-it-does]

- **Pageviews.** Sends one when it initializes, then one on every `history.pushState`, `history.replaceState` and `popstate`. Turn this off with `autoPageviews: false`.
- **Custom events.** `supapulse.event(name, properties)` sends a named event with any JSON-serializable properties.
- **Sessions.** Each page load gets a random session ID, kept in memory. Revenue can use it to link a payment to the visit. See [Sessions](https://supapulse.app/docs/core/sessions).
- **Identify.** `supapulse.identify(userId)` links the visitor to your customer ID, so revenue is credited to the visit that brought them. See [Revenue attribution](https://supapulse.app/docs/revenue/attribution).
- **Delivery.** Sends with `navigator.sendBeacon` and falls back to `fetch` with `keepalive`. Failed `fetch` sends are retried with exponential backoff, and `429` responses wait for `Retry-After`.

It stores nothing in the browser: no cookies, no `localStorage`, no `sessionStorage`.

## Core or React? [#core-or-react]

| | `@supapulse/core` | `@supapulse/react` |
| --- | --- | --- |
| Works with | Any framework, or none | React 16.8 and later |
| API | A `Supapulse` instance | `<SupapulseProvider>`, `useSupapulse`, `useEvent`, `usePageview` |
| Route changes | Tracked through the History API | Same, since it uses core underneath |

`@supapulse/react` creates and initializes a core tracker for you. Use it in React apps; use core everywhere else. See the [React overview](https://supapulse.app/docs/react/overview).

## Example [#example]

```ts
import { Supapulse } from '@supapulse/core';

const supapulse = new Supapulse();
supapulse.init({ apiToken: 'pub_your_token' });

// A pageview was sent on init. Track an event:
supapulse.event('signup', { plan: 'growth' });

// After login, link the visitor to your customer ID:
supapulse.identify('user_123');

// Optional: pass these through checkout to attribute revenue to this visit:
const sessionId = supapulse.getSessionId();
const fingerprint = await supapulse.getVisitorFingerprint();
```

## How a pageview gets counted [#how-a-pageview-gets-counted]

1. The tracker posts `{ type: 'pageview', data: { url, path, referrer, title, locale, utm_* , session_id } }` to `/api/ingest` with the public token.
2. The API checks the token and the request's `Origin`, queues the event and answers `202`.
3. A worker builds the visitor hash from the IP address, user agent, site and salt, looks up the country, parses the browser, OS and device type from the user agent, and stores the pageview without the IP address.

The tracker doesn't compute the visitor hash. `getVisitorFingerprint()` asks the server for it when you need it, for revenue; see the [API reference](https://supapulse.app/docs/core/api-reference#getvisitorfingerprint).

## Next steps [#next-steps]

- [Install the package](https://supapulse.app/docs/core/installation)
- [Track pageviews and events](https://supapulse.app/docs/core/usage)
- [All configuration options](https://supapulse.app/docs/core/configuration)
