@offstage/browser
v0.0.1
Published
Offstage analytics browser SDK
Readme
@offstage/browser
The browser SDK for Offstage analytics. Lightweight, dependency-free, and works in any modern browser.
Install
pnpm add @offstage/browserQuick start
import { Offstage } from "@offstage/browser";
const offstage = new Offstage({
apiKey: "pk_live_...",
});
offstage.track("signup_completed", { plan: "pro" });
offstage.identify("user_123", { email: "[email protected]" });
offstage.pageview();By default the SDK auto-tracks pageviews on pushState/popstate and posts events in batches.
API
new Offstage(options)
| Option | Type | Default | Description |
| --------------- | -------------------------- | --------------------- | --------------------------------------------------------------------------- |
| apiKey | string | required | Your Offstage publishable API key. |
| host | string | https://offstage.sh | Override the ingest host (self-hosted deployments). |
| autoPageviews | boolean | true | Patch history.pushState/replaceState and emit a pageview on navigation. |
| consent | boolean | true | Set to false to no-op until consent is granted (see "Consent" below). |
| enabled | boolean | true | Hard kill switch. Useful for enabled: import.meta.env.PROD. |
| onError | (error: unknown) => void | swallow | Called when the SDK catches an internal error. Tracking never throws. |
Methods
track(event: string, properties?: Record<string, unknown>): voididentify(userId: string, traits?: Record<string, unknown>): voidpageview(path?: string): void— defaults to the currentlocation.pathname.destroy(): void— flushes the queue, restoreshistory, and disables further tracking.
The SDK is SSR-safe: instantiating it during server rendering is a no-op.
Consent
The SDK respects navigator.doNotTrack automatically — when DNT is on, all tracking calls become no-ops.
To gate on your own consent banner, pass consent: false while the user hasn't opted in, then re-instantiate with consent: true once they do:
let offstage: Offstage | null = null;
function start() {
offstage = new Offstage({ apiKey: "pk_live_...", consent: true });
}
if (userHasConsented()) start();
// On "Accept":
banner.onAccept(() => start());
// On "Reject":
banner.onReject(() => offstage?.destroy());Storage
@offstage/browser uses localStorage for the visitor ID. It never sets cookies.
