Browser SDK
The core entry of @syntarie/tracking exposes everything you need for
pageview, custom events, identification, consent, and identity reads. The
auto-capture features (Web Vitals, errors, clicks, scroll depth, engaged
time) live under their own subpaths.
Initialise
Section titled “Initialise”import { init } from '@syntarie/tracking';
init({ siteId: 'site_marketing', host: 'https://collect.example.com', // optional: sessionTimeout: 30 * 60 * 1000, respectDnt: true, mode: 'cookied', defaultConsent: 'unknown', sampling: { mousemove: 0.1 },});InitOptions
Section titled “InitOptions”| Field | Type | Default | Notes |
|---|---|---|---|
siteId | string | required | Issued by your Leatsmap deployment. Throws on empty. |
host | string | required | Collector origin (scheme + host). Throws on empty. |
sessionTimeout | number | 30 * 60 * 1000 | ms. Negative / non-finite values clamp silently. |
respectDnt | boolean | true | When true, a DNT-blocked init never installs listeners. |
mode | 'cookied' | 'cookieless' | 'cookied' | Cookieless uses a daily-rotating fingerprint. |
defaultConsent | 'unknown' | 'granted' | 'unknown' | Pass 'granted' if you obtained consent before bootstrap. |
sampling | Record<string, number> | {} | Per-event-type rates in [0, 1]. |
Calling init more than once is a no-op for the second call onward.
Track custom events
Section titled “Track custom events”import { track } from '@syntarie/tracking';
track('checkout_completed', { order_id: 'ord_42', total_cents: 4900, currency: 'USD',});name becomes the wire type discriminator. props is sanitized (string
clamp, function / symbol drop) before queuing. Empty name is dropped
silently. Calls before init are dropped.
For type-safe track() calls narrowed to your tracking plan, see
TypeScript codegen.
Identify users
Section titled “Identify users”import { identify } from '@syntarie/tracking';
identify('user_42', { plan: 'pro' });Binds the current anon_id to a known user_id. If a different user_id
was previously stored, Leatsmap emits a merge event before the new
identify so cross-device timelines stay consistent. Empty / non-string
userId produces a console.warn and is otherwise a no-op (the SDK never
throws from public surfaces inside the host page).
Pageviews
Section titled “Pageviews”init() records the first pageview automatically and listens for SPA
navigation (pushState / replaceState / popstate). You do not need to
call pageview() manually in 99 % of apps. If your router uses a non-history
mechanism, call captureContext(url) followed by your custom emit.
Consent
Section titled “Consent”import { grantConsent, revokeConsent, getConsentState } from '@syntarie/tracking';
grantConsent(); // optional: pass a token attached as X-Consent on every requestrevokeConsent(); // purges the in-memory queue immediatelygetConsentState(); // 'unknown' | 'granted' | 'revoked'While consent is 'unknown' (the default), events queue in memory but no
network request goes out. grantConsent() drains the queued events.
revokeConsent() empties the queue and makes every subsequent send a no-op
for the rest of the page lifetime.
See Consent gating for the server-side enforcement.
Identity reads
Section titled “Identity reads”import { getUserId, getAnonId, getSessionId } from '@syntarie/tracking';
getUserId(); // string | null — null if identify() never rangetAnonId(); // string — UUID in cookied mode, daily fingerprint in cookieless modegetSessionId(); // string — mints a new session id if the inactivity window has lapsedgetSessionId() extends lastActiveTs as a side effect.
Context
Section titled “Context”import { captureContext, getCurrentContext } from '@syntarie/tracking';
captureContext('https://example.com/pricing');// returns: { utm, referrer, viewport, screen, language, timezone, ua }
getCurrentContext(); // EventContext | nullcaptureContext is called automatically on every pageview; you only need to
call it manually if you are wiring your own custom navigation hook.
import type { InitOptions, TrackingEvent, ConsentState,} from '@syntarie/tracking';TrackingEvent is exported only for type narrowing in adjacent modules
(e.g. the errors and engaged-time subpath signatures). Customers do not
construct TrackingEvent instances directly.
What’s NOT public
Section titled “What’s NOT public”The SDK exports send, getConfig, and getQueueForTests from the core
entry for use by the opt-in subpaths. They are not part of the contract — do
not import them in production code. Test seams (__resetForTests,
__resetConsentForTests, __resetIdentifyForTests, etc.) are private.