JavaScript SDK
The PennyLens SDK exposes a small global API for tracking events, identifying users, and controlling capture at runtime. Once the snippet from Installation loads, the SDK is available as window.PennyLens.
Loading and readiness
The script tag loads asynchronously. While the SDK initializes, any calls you make are queued and replayed once it's ready — so you can call PennyLens.track(...) immediately after the snippet without race conditions.
PennyLens.track("hero_cta_clicked");
To wait explicitly for readiness:
PennyLens.ready(() => {
console.log("PennyLens is ready");
});
Methods
track(event, properties?)
Records a custom event. Property values must be JSON-serializable.
PennyLens.track("checkout_started", {
cart_value: 89.99,
item_count: 3,
currency: "USD",
});
| Argument | Type | Notes |
| --- | --- | --- |
| event | string | Event name. Lowercase with underscores by convention. |
| properties | object | Optional. Nested objects and arrays are flattened to one level. |
identify(userId, traits?)
Attributes the current session to a known user. See User identification for the full behavior.
PennyLens.identify("user-7281", {
email: "alex@example.com",
plan: "pro",
});
pause() / resume()
Pauses event capture without unloading the SDK. Useful for consent flows — call pause() before the user accepts your privacy banner, then resume() after.
PennyLens.pause();
// Once consent is granted:
PennyLens.resume();
Calls made while paused are dropped silently — they aren't queued.
reset()
Clears the in-memory identity and starts a new anonymous session. Call this on logout so the next visitor on the device isn't attributed to the previous user.
PennyLens.reset();
recordSession(enabled)
Toggles session recording for the current and future sessions on this device. When called with false, the recording layer detaches; no DOM mutations are captured.
PennyLens.recordSession(false);
See Session recordings for the full reference.
setProperty(key, value) / removeProperty(key)
Attaches a persistent property to every subsequent event from this session — useful for things like experiment variants or A/B test buckets.
PennyLens.setProperty("experiment_checkout_v2", "treatment");
Configuration
When initializing via npm, pass options to init():
import { init } from "@pennylens/tracker";
init({
siteId: "YOUR_SITE_ID",
region: "eu-west-1",
sessionRecording: true,
maskInputs: true,
consent: "opt-in",
});
| Option | Type | Default | Notes |
| --- | --- | --- | --- |
| siteId | string | — | Required. Find in project settings. |
| region | "eu-west-1" | "eu-central-1" | "us-east-1" | "eu-west-1" | Data ingestion region. Business plan only for non-default regions. |
| sessionRecording | boolean | true | Disable to skip the rrweb layer entirely. |
| maskInputs | boolean | true | When true, all form inputs are masked in recordings. |
| consent | "opt-out" | "opt-in" | "opt-out" | Set to "opt-in" to require explicit resume() before any capture. |
| sampling | number | 1.0 | Fraction of sessions to record (0.0–1.0). Useful for high-traffic sites. |
| debug | boolean | false | Logs SDK activity to the browser console. |
Script-tag installs accept the same options via data-* attributes (e.g. data-region="eu-central-1").
TypeScript
The npm package ships types out of the box:
import type { PennyLensClient } from "@pennylens/tracker";
declare global {
interface Window {
PennyLens: PennyLensClient;
}
}
Next steps
- User identification — deep-dive on
identifyand session merging - Session recordings — recording controls and retention
- Event Tracking — auto-tracked and custom events