Skip tracking in the heatmap preview iframe - #4535
anandghegde wants to merge 3 commits into
Conversation
The heatmap report loads the tracked page in an iframe, so the site's own tracker recorded a page view every time a heatmap was opened. Name the preview frame umami.disabled and have the tracker treat that window name like the existing umami.disabled localStorage flag. Fixes umami-software#4529
|
@anandghegde is attempting to deploy a commit to the Umami Software Team on Vercel. A member of the Team first needs to authorize it. |
Greptile SummaryThis PR prevents heatmap previews from generating analytics by naming the preview iframe
Confidence Score: 4/5The PR appears safe to merge after considering a non-blocking hardening issue around accidentally disabling analytics in unrelated named top-level tabs. The intended heatmap suppression works, but the unconditional Files Needing Attention: src/tracker/index.ts
|
| Filename | Overview |
|---|---|
| src/app/(main)/websites/[websiteId]/(reports)/heatmaps/Heatmap.tsx | Names the cross-origin heatmap preview iframe so updated tracker scripts can recognize and suppress preview traffic. |
| src/tracker/index.ts | Adds browsing-context-name opt-out behavior, but currently applies it to top-level named tabs as well as preview frames. |
| src/tracker/index.test.ts | Verifies that automatic and manual tracker activity sends no requests when the browsing context has the opt-out name. |
Reviews (1): Last reviewed commit: "Skip tracking in the heatmap preview ifr..." | Re-trigger Greptile
| disabled || | ||
| !website || | ||
| localStorage?.getItem('umami.disabled') || | ||
| window.name === 'umami.disabled' || |
There was a problem hiding this comment.
The raw window.name check also disables tracking in top-level tabs named umami.disabled, such as pages opened through window.open(url, 'umami.disabled') or links using that target. Because the name persists across navigation, every pageview, event, identify call, and performance event is silently dropped outside the heatmap preview. This non-blocking concern can be avoided by restricting the signal to an embedded browsing context.
Knowledge Base Used:
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
There was a problem hiding this comment.
Good catch, fixed in 3678842. The window-name check now also requires top !== window, so it only applies inside a frame (the heatmap preview always is) and a top-level tab with that name keeps tracking. Added a test for the top-level case alongside the framed one.
A top-level tab opened with that name (window.open or a link target) keeps the name across navigation, so it would silently stop tracking. The heatmap preview is always framed, so require top !== window.
3678842 to
51d6304
Compare
|
Please resolve conflicts, thanks! |
|
Conflicts resolved in 1f4ac7d — merged
|
The heatmap report shows the tracked page inside an iframe. That page has the Umami script on it, so every time someone opens a heatmap the site records a page view (and the recorder can start too, since it waits for the tracker's session).
The dashboard can't use the existing
umami.disabledlocalStorage flag here, because the iframe is cross-origin and has its own storage. So this names the preview frameumami.disabled, and when the tracker is running inside a frame (top !== window) withwindow.name === 'umami.disabled', it treats that the same way it treats the localStorage flag. It's one line in each file. The frame check keeps top-level tabs that happen to carry that name (e.g.window.open(url, 'umami.disabled')) tracking normally. The recorder doesn't need a change: it only sends data once the tracker has a session, and that never happens in the preview.Same-name frames on other sites would also skip tracking. That only affects someone who chooses to embed their own page under that name, so it seemed fine. Happy to use a different name or a different signal if you'd prefer.
Note that the preview uses whatever tracker script the site loads, so the fix only applies once the site gets the updated
script.js.How I tested it
window.name = 'umami.disabled', no requests are sent; in a top-level window with the same name, tracking still happens (pnpm vitest run src/tracker).next dev). I made a test site on another origin that loadsscript.jsandrecorder.jswith heatmaps turned on, clicked around in it with headless Chromium to create heatmap data, then opened Heatmaps and picked the page:devwithout the change, the pageview count went from 1 to 2, and the iframe sent/api/send.biome checkis clean on the changed files.pnpm check:trackerpasses.Fixes #4529
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.