Skip to content

fix: guard analytics track() against non-callable window.gtag - #1092

Open
adimiz1 wants to merge 2 commits into
masterfrom
fix/analytics-gtag-guard
Open

adimiz1 wants to merge 2 commits into
masterfrom
fix/analytics-gtag-guard

Conversation

@adimiz1

@adimiz1 adimiz1 commented Sep 20, 2026

Copy link
Copy Markdown
Contributor

Summary

  • _initAnalytics() (src/video-player.js) checks window.gtag truthiness once, at setup, and bails with a console error if it's missing.
  • Once that gate passes, AnalyticsPlugin.track() (src/plugins/analytics/index.js) calls window.gtag('event', ...) unguarded on every tracked player event (play, pause, volumechange, ended, ...) with no re-check that it's still callable.
  • If gtag becomes non-callable after init — a consent-management tool (OneTrust, Cookiebot) swapping it out after a consent change, an ad-blocker, a CSP block — the next tracked event throws an uncaught TypeError: window.gtag is not a function. Same failure shape as ZD #388711 (window.ga era), just migrated to gtag.
  • Fix: guard the call site itself, not just setup.

Test plan

  • Manually reproduced on master: docs/analytics.html, ran window.gtag = 'not-a-function' in console, then played/paused/toggled volume — confirmed uncaught TypeError: window.gtag is not a function from AnalyticsPlugin.track for volumechange, play, pause.
  • Applied fix, repeated the same steps — confirmed no throw, tracking silently no-ops.
  • Confirmed real tracking (gtag('event', ...) calls / window.dataLayer growth) still fires normally when gtag is callable.
  • Reviewer: run npm run test:unit for regressions in analytics plugin coverage.

🤖 Generated with Claude Code

_initAnalytics() only checks window.gtag truthiness once at setup;
track() then calls window.gtag(...) unguarded on every tracked event
(play, pause, volumechange, etc). If gtag becomes non-callable after
init - a consent-management tool swapping it out, an ad-blocker, CSP -
the next tracked event throws an uncaught TypeError, breaking whatever
runs after it (same failure shape as ZD #388711 for the old window.ga
integration).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@adimiz1
adimiz1 requested a review from a team as a code owner September 20, 2026 07:45
@netlify

netlify Bot commented Sep 20, 2026

Copy link
Copy Markdown

Deploy Preview for cld-video-player ready!

Name Link
🔨 Latest commit 3b7de63
🔍 Latest deploy log https://app.netlify.com/projects/cld-video-player/deploys/6aaf909988497700080303b7
😎 Deploy Preview https://deploy-preview-1092--cld-video-player.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify

netlify Bot commented Sep 20, 2026

Copy link
Copy Markdown

Deploy Preview for cld-vp-esm-pages ready!

Name Link
🔨 Latest commit 3b7de63
🔍 Latest deploy log https://app.netlify.com/projects/cld-vp-esm-pages/deploys/6aaf909919eefa00096ee562
😎 Deploy Preview https://deploy-preview-1092--cld-vp-esm-pages.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Covers both sides of the track() guard: real gtag calls still fire
normally, and a non-callable gtag (consent tool, ad-blocker) no longer
errors. Since videojs's event dispatcher catches handler exceptions
and logs them via videojs.log.error instead of rethrowing, the
non-callable case asserts against that log spy rather than a thrown
error.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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