Idle-aware
The engagement timer pauses once the reader goes idle, so “AFK reading” doesn’t inflate your numbers.
@adpharm/silo-analytics is a drop-in replacement for @segment/analytics-next
that adds automatic Time on Page tracking with built-in guardrails for SPAs
(React Router) and SSR environments. You swap one import; the engagement plugin
auto-registers with sensible defaults.
import { AnalyticsBrowser } from "@adpharm/silo-analytics";
export const analytics = AnalyticsBrowser.load({ writeKey: "your-write-key",});GA4’s engagement_time_msec is the de-facto standard for “time on page,” but its
client-side mechanics have documented weaknesses: it keeps counting while a
reader is idle (“AFK reading”), it leans on the unreliable beforeunload event,
and it offers no first-class hook for SPA route changes. This library reproduces
GA4’s verified three-condition engagement rule (the timer only advances when
the page is visible and focused and within a pageshow→pagehide
window) and then closes those gaps:
Idle-aware
The engagement timer pauses once the reader goes idle, so “AFK reading” doesn’t inflate your numbers.
Crash-resilient
A bounded-exponential heartbeat caps data loss on a browser crash or mobile tab-kill to ≤ one schedule-step.
SPA-ready
Internal route changes are detected via Segment page events + browser
back/forward (popstate); engagement resets cleanly per page-view.
Consent-aware
Optional @segment/analytics-consent-tools integration stamps every beacon
with context.consent.categoryPreferences for server-side enforcement.
eventName default is on the Configuration page).scroll_depth_max_px plus
estimated percentage fields when the page is scrollable.pagehide + visibilitychange + Safari-only
beforeunload; failed beacons persist to localStorage and replay on next load.messageId, page_view_id, and
sequence so retries collapse cleanly.