fix(pixel): drop synthetic above-fold scroll_depth event (SDK-275)#2869
Merged
Conversation
The previous fix (v0.1.1) used a ResizeObserver to detect when the document grew beyond the viewport, but the synthetic above-fold event still produced false positives on SPAs and pages with internal scroll containers — where document.documentElement.scrollHeight is permanently equal to window.innerHeight regardless of actual content depth. Confirmed in the wild on godsunchained.com, which uses an internal .website-content scroll container with overflow: auto. Drop the synthetic event entirely and align with PostHog / Segment / GTM behaviour: only fire scroll_depth on real scroll events. On pages where the document doesn't scroll, no milestone fires. This trades the bounce-filter signal on legitimately short pages for eliminating an entire class of false positives. Net bundle impact: -181 bytes gzip vs v0.1.1, -89 bytes vs pre-SDK-275. Follow-up SDK-XXX will look at proper scroll tracking on pages with internal scroll containers (capture-phase scroll listening). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
View your CI Pipeline Execution ↗ for commit a327b95
☁️ Nx Cloud last updated this comment at |
✅ Pixel Bundle Size — @imtbl/pixel
Budget: 10.00 KB gzipped (warn at 8.00 KB) |
- README: scroll_depth row no longer mentions the removed aboveFold property or 2s dwell. - autocapture.ts: tighten the setupScrollTracking jsdoc; drop the ticket reference (belongs in the PR description, not source code) and the competitor name-check (changelog territory). - autocapture.test.ts: remove the 'does not include aboveFold property' test — it was a redundant guard once the property was gone from the source, and the existing toEqual assertions cover it. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
nattb8
approved these changes
May 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Hotfix for SDK-275. The v0.1.1 ResizeObserver fix in #2868 addressed the original "page grew after init" race, but the synthetic
aboveFold: true depth: 100event was still being emitted on SPAs and pages with internal scroll containers. Confirmed on https://godsunchained.com/ wheredocument.documentElement.scrollHeightis permanently equal towindow.innerHeightbecause the page uses a<div class="website-content">withoverflow: autoas its actual scroll container.The bug is architectural — any check based on the document element gives the wrong answer when the document itself isn't the scroller. ResizeObserver doesn't help: the document height is locked, so the "page grew" branch can never trigger.
Fix: drop the synthetic above-fold event entirely. Match PostHog / Segment / GTM behaviour and only fire
scroll_depthon real scroll events. On pages where the document doesn't scroll, no milestone fires. The previous bounce-filter signal on legitimately short pages is lost, but in exchange we eliminate an entire class of false positives — and none of the established lightweight trackers do this anyway, so we're not losing competitive ground.Bundle size
CI will post the authoritative delta. As a sanity check, locally measured: 5,670 B gzip (down 181 B from v0.1.1, down 89 B from the pre-SDK-275 baseline). Removing complexity wins.
Follow-up
A new Linear ticket will be opened to cover proper scroll-depth tracking on pages with internal scroll containers (capture-phase scroll listening, ~+50–100 B), plus documenting the iframe limitation in
docs.immutable.com— that one needs a separate PR againstimmutable/documentation.Test plan
🤖 Generated with Claude Code
Note
Medium Risk
Changes
scroll_depthsemantics by removing the synthetic 100% event on non-scrollable pages, which may affect downstream analytics/dashboards that relied on those events. Logic is localized to autocapture and is covered by updated tests, with no auth/PII impact.Overview
Removes the synthetic above-the-fold
scroll_depthemission (previouslydepth: 100after a dwell viaResizeObserver) and now only emits scroll milestones when the document is actually scrollable and the user scrolls.Updates tests to drop
ResizeObserver/timer-based behavior and assert that non-scrollable pages never emitscroll_depth(including on spurious scroll events), updates README documentation accordingly, and bumps@imtbl/pixelto0.1.2.Reviewed by Cursor Bugbot for commit a327b95. Bugbot is set up for automated code reviews on this repo. Configure here.