Web SDK
@cohorly/web is the browser SDK. It is built on the shared core with localStorage persistence, a fetch/sendBeacon transport (so events survive tab close and navigation), and optional SPA pageview autotracking.
Install
pnpm add @cohorly/web
# or: npm install @cohorly/webInitialize
Call init() once at your app entry point. apiHost is required; pass your project token so events route to the right project.
import { init } from "@cohorly/web";
const cohorly = init({
apiHost: "https://api.cohorly.com",
token: "YOUR_PROJECT_TOKEN",
trackPageviews: true,
});After init() has run once, you can import the named cohorly singleton anywhere instead of threading the returned instance through your app:
import { cohorly } from "@cohorly/web";
cohorly.track("Button Clicked", { button: "checkout" });init() is SSR-safe: browser-only APIs (localStorage, window, sendBeacon) fall back to in-memory/no-op implementations when unavailable.
Options
| Option | Type | Notes |
|---|---|---|
apiHost | string | Required. Base URL of your Cohorly server. |
token | string | Project token stamped on every event and request. |
trackPageviews | boolean | Autotrack SPA pageviews. |
flushIntervalMs | number | How often the queue auto-flushes. |
batchSize | number | Flush once this many events are queued. |
superProperties | object | Properties merged into every event from the start. |
debug | boolean | Verbose logging. |
Track events
track(event, properties?) queues an event. The SDK automatically merges in $browser, $os, $current_url, and screen size, plus distinct_id, time, $insert_id, and $lib.
cohorly.track("Signed Up", { plan: "pro" });
cohorly.track("Item Added", { sku: "A-100", price: 29 });Identify
identify(id) switches the current anonymous user to a known id. On the first call after being anonymous it sends an /alias request so pre-login and post-login activity merge into one profile, then persists the new id.
await cohorly.identify("user_123");Use reset() on logout to generate a fresh anonymous id:
cohorly.reset();Super properties
Super properties are merged into every subsequent event. Register and unregister them with register() / unregister(). Event-level properties override super properties of the same key.
cohorly.register({ app_version: "1.2.3", plan: "free" });
cohorly.track("Viewed Page"); // includes app_version and plan
cohorly.unregister("plan");People profiles
Update the current user's profile through cohorly.people. These map to the /engage endpoint.
await cohorly.people.set({ name: "Ada Lovelace", plan: "pro" });
await cohorly.people.setOnce({ first_seen: Date.now() });
await cohorly.people.increment({ logins: 1 });
await cohorly.people.unset(["temp_flag"]);
await cohorly.people.delete();Flush and accessors
await cohorly.flush(); // send the queued batch now
const id = cohorly.getDistinctId();
const anon = cohorly.isAnonymous();The queue is persisted to localStorage, so events survive reloads and are retried on the next flush if a request fails.
Keeping the token out of the bundle
Passing token to init() embeds it in your client JS. If you would rather not, proxy ingestion server-side with @cohorly/nextjs's createCohorlyProxy() and omit token here. See the Next.js SDK.