Conversation
…1468) Co-authored-by: James Shebester <James.Shebester@optimizely.com>
…1467) * Add opt-in extended activity tracking with activity_metrics entity Attach quantitative activity metrics (mouse distance, scroll distance, key presses, clicks, touches) to page_ping events when extendedActivityTracking is enabled. Reuses existing DOM event handlers with zero overhead when the feature is off. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add change files * Add API extractor changes * Address review feedback --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Release PR for v4.8.0, bundling two main updates: opt-in extended activity tracking (via a new activity_metrics context entity) and an Optimizely X plugin fix to correctly capture campaignId for personalization campaigns.
Changes:
- Add opt-in activity metrics collection and attach
activity_metricsentity to page pings / callback data. - Update Optimizely X plugin to use campaign state APIs and bump the summary context schema to
1-1-0(addscampaignId). - Export new
ActivityMetricstype through public browser-tracker API/docs and add Jest tests for the new metrics behavior.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| trackers/browser-tracker/src/api.ts | Re-export ActivityMetrics from @snowplow/browser-tracker-core in the public browser-tracker API surface. |
| plugins/browser-plugin-optimizely-x/src/index.ts | Switch to getCampaignStates() to populate campaignId, and bump summary schema version to 1-1-0. |
| plugins/browser-plugin-optimizely-x/src/contexts.ts | Extend Optimizely summary context type with optional campaignId. |
| libraries/browser-tracker-core/test/tracker/activity_metrics.test.ts | Add tests covering activity metric accumulation/reset and callback payload behavior. |
| libraries/browser-tracker-core/src/tracker/types.ts | Introduce ActivityMetrics type and activityMetrics?: boolean config flag; include metrics in callback data. |
| libraries/browser-tracker-core/src/tracker/schemata.ts | Add ACTIVITY_METRICS_SCHEMA constant. |
| libraries/browser-tracker-core/src/tracker/index.ts | Implement metrics collection, snapshotting, and context attachment during activity tracking. |
| common/changes/@snowplow/browser-tracker/feature-extended-activity-tracking_2026-04-06-13-19.json | Add changelog entry for browser-tracker release notes. |
| common/changes/@snowplow/browser-tracker-core/feature-extended-activity-tracking_2026-04-06-13-19.json | Add changelog entry for browser-tracker-core release notes. |
| common/changes/@snowplow/browser-plugin-optimizely-x/fix-optimizely-personalization-campaign-id_2026-04-20-08-00.json | Add changelog entry for Optimizely X plugin fix. |
| api-docs/docs/browser-tracker/browser-tracker.api.md | Update generated API docs for the new ActivityMetrics type and config flag. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| let activityMetrics: ActivityMetrics | undefined; | ||
| if (isActivityMetricsEnabled()) { | ||
| activityMetrics = getActivityMetrics(); | ||
| context = context.concat([{ schema: ACTIVITY_METRICS_SCHEMA, data: activityMetrics }]); | ||
| } | ||
| cb({ context, pageViewId: getPageViewId(), minXOffset, minYOffset, maxXOffset, maxYOffset, activityMetrics }); | ||
| resetMaxScrolls(); | ||
| if (isActivityMetricsEnabled()) { |
There was a problem hiding this comment.
executePagePing uses isActivityMetricsEnabled() (global OR across both activity-tracking configurations) to decide whether to attach/reset metrics. This means opting into activityMetrics for only the callback (or only page pings) will still attach the entity for the other configuration and can also reset the shared counters at the wrong time, producing incorrect/zeroed metrics when both activity tracking mechanisms are enabled. Consider gating attach/reset on the current config.activityMetrics and handling the “both enabled” case explicitly (e.g., separate accumulators per config or coordinated reset after both callbacks run).
| let activityMetrics: ActivityMetrics | undefined; | |
| if (isActivityMetricsEnabled()) { | |
| activityMetrics = getActivityMetrics(); | |
| context = context.concat([{ schema: ACTIVITY_METRICS_SCHEMA, data: activityMetrics }]); | |
| } | |
| cb({ context, pageViewId: getPageViewId(), minXOffset, minYOffset, maxXOffset, maxYOffset, activityMetrics }); | |
| resetMaxScrolls(); | |
| if (isActivityMetricsEnabled()) { | |
| const activityMetricsEnabledForConfig = !!config.activityMetrics; | |
| let activityMetrics: ActivityMetrics | undefined; | |
| if (activityMetricsEnabledForConfig) { | |
| activityMetrics = getActivityMetrics(); | |
| context = context.concat([{ schema: ACTIVITY_METRICS_SCHEMA, data: activityMetrics }]); | |
| } | |
| cb({ context, pageViewId: getPageViewId(), minXOffset, minYOffset, maxXOffset, maxYOffset, activityMetrics }); | |
| resetMaxScrolls(); | |
| if (activityMetricsEnabledForConfig) { |
| if (isActivityMetricsEnabled()) { | ||
| if (activityMetricsState.lastScrollX !== undefined && activityMetricsState.lastScrollY !== undefined) { | ||
| activityMetricsState.metrics.scrollDistance += Math.abs(x - activityMetricsState.lastScrollX) + Math.abs(y - activityMetricsState.lastScrollY); | ||
| } | ||
| activityMetricsState.lastScrollX = x; | ||
| activityMetricsState.lastScrollY = y; | ||
| } |
There was a problem hiding this comment.
scrollDistance accumulation logic is new here, but the added test suite doesn’t currently include a positive assertion that scrollDistance increases when scroll offsets change (only that it remains 0 in some cases). Adding a unit test that mutates scroll offsets and dispatches scroll would help prevent regressions in this metric.
Upgrades @docusaurus/core and related packages from 3.4.0 to 3.10.0 and adds npm overrides for serialize-javascript, lodash, and webpackbar to clear the remaining high-severity transitive vulnerabilities flagged by Snyk (node-forge, svgo, minimatch, brace-expansion, serialize-javascript RCE, lodash prototype pollution). npm audit now reports 0 vulnerabilities and docusaurus build succeeds. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This release adds extended activity tracking with new activity metrics tracked using the
activity_metricsentity.It also enahences the optimizely-x plugin to capture the
campaignIdfor personalization campaigns.Enhancements