CohorlyDocs
GitHub

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

bash
pnpm add @cohorly/web
# or: npm install @cohorly/web

Initialize

Call init() once at your app entry point. apiHost is required; pass your project token so events route to the right project.

ts
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:

ts
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

OptionTypeNotes
apiHoststringRequired. Base URL of your Cohorly server.
tokenstringProject token stamped on every event and request.
trackPageviewsbooleanAutotrack SPA pageviews.
flushIntervalMsnumberHow often the queue auto-flushes.
batchSizenumberFlush once this many events are queued.
superPropertiesobjectProperties merged into every event from the start.
debugbooleanVerbose 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.

ts
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.

ts
await cohorly.identify("user_123");

Use reset() on logout to generate a fresh anonymous id:

ts
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.

ts
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.

ts
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

ts
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.