Skip to content

Suppress false-positive dead clicks across all video players#18569

Open
posthog[bot] wants to merge 3 commits into
masterfrom
posthog-code/merch-video-dead-clicks
Open

Suppress false-positive dead clicks across all video players#18569
posthog[bot] wants to merge 3 commits into
masterfrom
posthog-code/merch-video-dead-clicks

Conversation

@posthog

@posthog posthog Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Summary

The merch launch video (#18431) caused the /merch page's $dead_click rate to spike from July 14: clicks on the Wistia player (play/pause, video body, scrubber) change playback state without the DOM mutation / navigation / scroll that PostHog's dead-click heuristic looks for, so a working video registered as false-positive $dead_click events.

That false positive isn't specific to merch — it applies to every interactive video player on the site. So the fix is now applied at the shared component level rather than only on the merch page.

Fix

ph-no-deadclick tells posthog-js's dead-click detector to skip capture when the class is on the clicked element or any ancestor (it's in the default ignore list, and the project's remote config has captureDeadClicks: true). Normal autocapture is unaffected — it mirrors the existing rageclick tuning in posthog-init.js.

  • WistiaEmbed — carries the class itself, covering merch and all other embeds (/code, /r/product-analytics, /slack, and MDX <WistiaEmbed> usages).
  • WistiaVideo and WistiaCustomPlayer — class added on their root wrappers (home demos, MCP page, wizard, product slides, /data-stack).
  • MerchVideoCard reverts to its original wrapper — the shared component handles it now.

Deliberately left alone, after checking each: ProductVideo (native <video>, mostly autoPlay muted loop with no controls — nothing to misclick), TypecaastPlayer (isolated shadow-root typing animation, not a scrubbable player), and TapePlayer (audio, not video).

Why

The video isn't broken — the metric was being inflated by ordinary video interaction, which masked genuine dead clicks and made the surface hard to monitor. Suppressing it at the player level restores a meaningful signal across the whole site, not just on merch.

Note on scope

A separate, pre-existing lower-volume pattern on /merch (clicks on the frozen body behind the product Drawer's scroll lock — body[pointer-events:none][data-scroll-locked]) also contributes to merch-page dead clicks. It predates the regression and isn't the driver, so it's intentionally left out and worth a separate look.

Test plan

  • On /merch and another Wistia page (e.g. /code), click the player (play, pause, scrub) and confirm no $dead_click events fire for the player, while other autocapture continues.
  • Confirm videos still play/pause/scrub exactly as before (marker class only; no behavior change).

Created with PostHog Code from an inbox report.

The merch launch video (Wistia embed, added in #18431) drove the merch page's
$dead_click rate up sharply from July 14: clicks on the player (play/pause, video
body, scrubber) change playback state without the DOM mutation PostHog's dead-click
heuristic looks for, so they were captured as false-positive $dead_click events.

Add `ph-no-deadclick` to the video card wrapper. posthog-js's dead-click detector
walks the clicked element's ancestors against the default ignore list
(`.ph-no-deadclick`, `.ph-no-capture`) and skips capture on a match, so this
suppresses only dead-click capture on the video; normal autocapture is unaffected.

Generated-By: PostHog Code
Task-Id: ff9a39ee-9ed4-44d1-b1e1-d2a864083bee
@github-actions

github-actions Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Deploy preview

Status Details Updated (UTC)
🟢 Ready View preview Jul 16, 2026 09:31AM

@github-actions

github-actions Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Bundle report

Total JS (gzip)

6.31 MiB (+0.3 KiB / +0.0%)

Eager graph (modules shipped in each entrypoint's initial chunks)

Entrypoint Eager size Budget Modules
app 15.60 MiB (+2.6 KiB / +0.0%) report-only 1945
Largest modules in the app closure
Module Size
css ./node_modules/.pnpm/css-loader@5.2.7_webpack@5.101.3/node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[8].oneOf[1].use[1]!./node_modules/.pnpm/postcss-loader@4.3.0_postcss@8.5.6_webpack@5.101.3/node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[8].oneOf[1].use[2]!./src/styles/global.css 711.1 KiB
./src/components/Stickers/Stickers.tsx 696.4 KiB
./.cache/caches/gatsby-plugin-mdx/mdx-scopes-dir/31a094f140f119e73085d847ae81b99b.js + 2 modules 629.5 KiB
./node_modules/.pnpm/@radix-ui+react-icons@1.3.2_react@18.3.1/node_modules/@radix-ui/react-icons/dist/react-icons.esm.js 481.4 KiB
./node_modules/.pnpm/rehype-raw@7.0.0/node_modules/rehype-raw/lib/index.js + 29 modules 395.1 KiB
./node_modules/.pnpm/@posthog+icons@0.36.6_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.cjs.js 364.8 KiB
./src/hooks/useCustomers.tsx + 54 modules 355.1 KiB
./node_modules/.pnpm/@posthog+icons@0.36.6_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js 354.8 KiB
./node_modules/.pnpm/react-markdown@8.0.7_@types+react@16.14.66_react@18.3.1/node_modules/react-markdown/lib/react-markdown.js + 88 modules 351.4 KiB
./node_modules/.pnpm/cloudinary-core@2.14.0_lodash@4.17.21/node_modules/cloudinary-core/cloudinary-core.js 281.9 KiB
./src/components/ProductComparisonTable/index.tsx + 120 modules 278.5 KiB
./node_modules/.pnpm/d3@7.9.0/node_modules/d3/src/index.js + 208 modules 247.4 KiB
./src/components/Pricing/PricingSlider/Slider.tsx + 87 modules 239.9 KiB
./gatsby-browser.tsx + 41 modules 239.8 KiB
./src/components/SearchUI/index.tsx + 73 modules 223.4 KiB

Eager-graph budgets are report-only until a baseline is established. Sizes are gzip of public/**/*.js; eager size is webpack module source bytes for the modules actually shipped in the entrypoint's initial chunks (post-tree-shake).

Move the `ph-no-deadclick` fix from the merch page wrapper into the shared video player components so every embed benefits, not just the merch launch video.

- `WistiaEmbed` now carries the class (covers merch and all other embed usages)
- `WistiaVideo` and `WistiaCustomPlayer` get it on their root wrappers too
- Reverts the per-page wrapper on `MerchVideoCard` since the shared component handles it

Also trims the verbose inline comment down to a single line per the team's feedback.

Generated-By: PostHog Code
Task-Id: de3cffba-fe6a-40f9-b449-8c49d9f47f09
@andrewm4894 andrewm4894 changed the title Stop merch launch video from generating false-positive dead clicks Suppress false-positive dead clicks across all video players Jul 16, 2026
@andyvan-ph andyvan-ph marked this pull request as ready for review July 16, 2026 09:19
@andyvan-ph

Copy link
Copy Markdown
Contributor

@smallbrownbike PostHog flagged this deadclick problem after the merch video went live and I figured it was probably a an issue everywhere.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants