Configuration
AnalyticsBrowser.load takes a single config object. The top level accepts the
standard @segment/analytics-next load settings and options (writeKey,
cdnURL, integrations, user, …) plus two silo-specific keys: env and
timeOnPage, and an optional consent block (see Consent).
timeOnPage options
Section titled “timeOnPage options”timeOnPage is Partial<> — override only what you need; apiHost defaults to
the Silo event gateway and writeKey inherits from the top level.
| Option | Type | Default | Description |
|---|---|---|---|
eventName | string | "Page Time Spent" | Event name sent with the beacon. |
minSeconds | number | 5 | Minimum seconds before sending an event. |
maxSeconds | number | 900 | Maximum seconds to cap the event at (15 minutes). |
idleSeconds | number | 30 | Seconds of zero user input after which the engagement counter pauses (audit §3 — GA4’s documented “AFK reading” weakness). Any of mousemove, mousedown, keydown, scroll, touchstart, click, wheel restarts it. Set to 0 to disable idle gating entirely. |
heartbeatSchedule | number[] | false | [30, 60, 120, 240, 480, 600] | Bounded-exponential heartbeat schedule in seconds (audit §6.3). Each fire dispatches a beacon with exitType: "heartbeat" carrying the engagement delta since the last beacon, then schedules the next fire at the NEXT step. The last value in the array caps and repeats forever. Schedule is clock-based, not engagement-based: a step advances whether or not the dispatch actually went out (sub-threshold deltas are skipped but the schedule still ticks). Resets to step 0 on navigation boundary and on visibility-return — both signal a fresh engagement window. The default is the audit recommendation. Pass false to disable heartbeats entirely. Pass a custom array to override (mostly useful for tests). |
scrollTracking | boolean | true | Document-relative scroll-depth tracking. When enabled, each beacon carries scroll_depth_max_px (deterministic peak scrollY since the page-view started) plus — when the page is actually scrollable — est_scroll_depth_max_pct and est_scroll_depth_pct. The est_ prefix on the pct fields signals lossiness: the denominator (scrollHeight - viewportHeight) can shift mid-session under lazy image / font swap / ad injection, so the percentage is directional, not authoritative. Set to false to suppress all three fields entirely. |
Notes on individual options
Section titled “Notes on individual options”idleSeconds — the AFK-reading gate
Section titled “idleSeconds — the AFK-reading gate”GA4’s documented weakness is that it keeps counting engagement while a reader is
idle. idleSeconds pauses the engagement timer after that many seconds of zero
user input; any of mousemove, mousedown, keydown, scroll, touchstart,
click, or wheel restarts it. Set to 0 to disable idle gating entirely.
Typical thresholds run 15–60s depending on content type (long-form reading
tolerates a higher value). See Time on Page.
heartbeatSchedule — bounded-exponential backoff
Section titled “heartbeatSchedule — bounded-exponential backoff”The heartbeat caps data loss on a browser crash or mobile tab-kill to ≤ one
schedule-step. The schedule is clock-based, not engagement-based: a step
advances on every fire whether or not the dispatch actually went out
(sub-threshold deltas are skipped, but the schedule still ticks). It resets to
step 0 on a navigation boundary and on visibility-return — both signal a fresh
engagement window. Pass false to disable heartbeats entirely. See
Time on Page.
scrollTracking
Section titled “scrollTracking”Toggles the three scroll-depth fields on every beacon. See
Scroll Depth for the full field contract and the est_
convention.
Storage-key namespacing
Section titled “Storage-key namespacing”env only namespaces storage keys — it does not tag events. Cookies and
localStorage become ajs_user_id_${writeKey}_${env} and
ajs_user_traits_${writeKey}_${env} so dev/staging/prod don’t share identities
across the same eTLD+1.