Clickport measures engagement beyond simple pageviews. The tracker automatically records how far visitors scroll and how long they actively spend on each page. These signals combine into a unified engagement score that appears across dashboard panels.
Scroll depth is the maximum vertical scroll position a visitor reaches on a page, expressed as a percentage from 0 to 100. The tracker calculates this by dividing the current scroll position by the total scrollable height of the document.
For each page a visitor views, Clickport records the furthest point they scrolled to. The value only increases. If a visitor scrolls to 78% of a blog post, that 78% is stored. If they scroll back up, the maximum remains 78%.
The tracker listens for scroll events and computes the percentage on every scroll. A ResizeObserver monitors the document body so that the scrollable height is recalculated when the page layout changes. This keeps percentages accurate on responsive pages or single-page applications where content loads dynamically.
Scroll depth is tracked per page, not per session. If a visitor views three pages with scroll depths of 60%, 80%, and 40%, those individual values are stored separately. The Pages panel shows per-page scroll, while the KPI bar and Sources panel show session-level averages.
Duration measures how long a visitor actively spends on your site. It is calculated from the first event to the last event in each session, but only counts time when the page is actually visible.
The tracker uses a start-stop timer. When the page loads, the timer starts. When the visitor switches to a different tab or minimizes the browser window, the timer pauses. When they return, it resumes. This prevents inflated durations from abandoned tabs.
Pausing is triggered by two signals:
visibilitychange event fires when the tab becomes hidden or visible again.blur and focus events fire when the browser window itself loses or gains focus.When the visitor navigates away or closes the tab, the tracker sends a final engagement update. This is triggered by both pagehide and beforeunload events for maximum browser coverage. The data is sent using fetch with the keepalive flag, which allows the request to complete even after the page has unloaded.
The tracker also sends incremental updates while the visitor is active. An update is only sent when duration changes by at least 3 seconds or the maximum scroll depth increases. This avoids unnecessary network requests.
Individual sessions are capped at 30 minutes (1,800 seconds) when calculating averages. This prevents a single outlier session from skewing your numbers. The cap applies to the KPI averages and panel aggregations. Individual session records in the Sessions panel still show the actual duration.
The engagement score is a 0-100 metric that combines scroll depth and duration into a single number. It appears as a colored percentage in the Sources, Pages, Countries, and other panels.
The engagement score averages two components, each normalized to a 0-100 scale:
A long blog post averaging 82% scroll and 240 seconds (4 minutes) duration:
A product page averaging 95% scroll and 720 seconds (12 minutes) duration:
A landing page averaging 18% scroll and 8 seconds duration:
Engagement scores are color-coded in dashboard panels to indicate quality at a glance:
Engagement metrics directly influence bounce rate. Clickport defines a bounce as a session meeting all four of these criteria:
This multi-criteria approach is more forgiving than traditional bounce rate, which only checks whether the visitor viewed a single page. For more details, see the KPIs documentation.
Clickport also tracks when visitors copy text from your pages. When a visitor selects and copies content, the tracker captures the event along with the first 200 characters of the copied text. This appears in the Sessions panel when you drill into individual sessions.
Copy events are a useful engagement signal. They often indicate that a visitor found your content valuable enough to save or share.
Engagement data follows this path from the visitor's browser to your dashboard:
pageleave event carries the total duration (in milliseconds) and maximum scroll depth (0-100).max_scroll_depth is set to the highest value seen across all pages in the session. duration is calculated as the time between the session start and the latest event.pagehide and beforeunload events to maximize reliability across browsers. Data is sent with fetch and keepalive: true, which allows the request to complete after the page begins unloading.