Skip to content

Automated metrics ​

Beyond the events you track explicitly, the tag automatically captures four categories of signal. Each is on by default and can be turned off via Configuration.

Web vitals (performance) ​

Real-user Core Web Vitals, captured with the browser's PerformanceObserver and sent on pagehide (or when the tab is hidden):

EventMetricProperty
web_vital_lcpLargest Contentful Paintvalue_ms
web_vital_inpInteraction to Next Paint (worst interaction)value_ms
web_vital_clsCumulative Layout Shiftvalue (unitless)
web_vital_fcpFirst Contentful Paintvalue_ms
web_vital_ttfbTime to First Bytevalue_ms

Disable with webVitals: false.

Errors & API monitoring ​

Two kinds of automatic error capture.

JavaScript exceptions ​

Unhandled errors and rejected promises fire $exception with the message, source file/line, and a truncated stack:

js
// captured automatically — fires window.periscale.track("$exception", { … })

Image load errors are ignored (too noisy). Stack traces are capped at 2000 characters; messages at 500.

API errors & slow responses ​

The tag patches window.fetch and watches calls to your proxy/backend paths (/api/proxy/ and /api/v1/business/website/). For each watched request:

  • a non-2xx response → api_error with endpoint, status_code, latency_ms, method
  • a network failure → api_error with status_code: 0 and the error message
  • a response slower than 2000 ms → slow_api_response with latency_ms

Disable with errors: false.

Engagement ​

Automatic behavioral signals that reveal friction and content quality:

EventFires whenProperties
scroll_depth_reachedThe visitor passes 25 / 50 / 75 / 100% of a pagedepth, pathname
time_on_pageOn navigation away or pagehideduration_ms, active_ms (active = tab visible)
rage_click≥ 3 clicks within 800 ms on the same elementtarget_tag, target_text, click_count
dead_clickA click that causes no navigation, no DOM change, and lands on a non-interactive elementtarget_tag, target_text

Scroll depth and time-on-page are SPA-aware: the tag hooks history.pushState / replaceState so virtual navigations (e.g. Next.js route changes) reset and flush correctly without a full page load.

Disable with engagement: false.

Conversion pixels & vendor tags ​

Some ad/analytics vendors can only fire in the browser. When your business configures them, the tag injects them automatically (toggle with vendorTags: false):

  • Microsoft Clarity — has no server-side ingestion API, so the JS tag is injected with your project id and clarity('identify', …) is called so Clarity sessions correlate with the Periscale distinct_id.
  • Facebook Pixel dedup — if your business uses server-side Conversions API (CAPI) and no fbq pixel is already on the page, the tag loads the Pixel and fires each conversion with eventID equal to the SDK event's UUID — the same id the worker sends to CAPI — so Meta deduplicates the browser and server events instead of double-counting.

If a fbq pixel is already present on the page, the tag leaves it alone and relies on the server-side CAPI path only.

© Periscale