From 3590345ea55ebc337319a31d304951f9e446c307 Mon Sep 17 00:00:00 2001 From: Joe Lencioni Date: Wed, 13 May 2026 16:42:19 -0500 Subject: [PATCH] Fire Docs Visited Plausible event on every docs page view Adds an onRouteDidUpdate client lifecycle hook that fires the "Docs Visited" custom event whenever the user lands on or navigates to a page under docs.happo.io. This lets us use docs visits as a top-of-funnel goal in Plausible (HAP-852). The tracker library is still lazy-loaded once and initialized only once; subsequent route changes reuse the cached module. Co-authored-by: Cursor --- src/clientModules/plausible.js | 68 ++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 7 deletions(-) diff --git a/src/clientModules/plausible.js b/src/clientModules/plausible.js index e74b431..67aacd1 100644 --- a/src/clientModules/plausible.js +++ b/src/clientModules/plausible.js @@ -1,9 +1,63 @@ -// Lazy-load the tracker library only on the client -if (typeof window !== 'undefined') { - import('@plausible-analytics/tracker').then(({ init }) => { - init({ - domain: 'docs.happo.io', - captureOnLocalhost: false, +// Lazy-load the tracker library only on the client and fire a "Docs Visited" +// custom event for every page view under docs.happo.io. Pageviews are also +// captured automatically by the tracker, but the custom event lets us use +// "Docs Visited" as a top-of-funnel goal in Plausible. + +let trackerPromise; + +function getTracker() { + if (!trackerPromise) { + trackerPromise = import('@plausible-analytics/tracker').then(mod => { + if (!window.__happoPlausibleInitialized) { + mod.init({ + domain: 'docs.happo.io', + captureOnLocalhost: false, + }); + window.__happoPlausibleInitialized = true; + } + return mod; + }); + } + return trackerPromise; +} + +function trackDocsVisited() { + getTracker() + .then(({ track }) => { + try { + track('Docs Visited', { + props: { path: window.location.pathname }, + }); + } catch (err) { + if (process.env.NODE_ENV !== 'production') { + // eslint-disable-next-line no-console + console.warn('Failed to track Docs Visited', err); + } + } + }) + .catch(() => { + // Tracker failed to load (e.g. blocked); ignore. }); - }); +} + +if (typeof window !== 'undefined') { + // Kick off the tracker init eagerly so the first pageview is captured even + // if the route lifecycle below doesn't fire (older Docusaurus versions). + getTracker(); +} + +export function onRouteDidUpdate({ location, previousLocation }) { + if (typeof window === 'undefined') { + return; + } + // Only fire when the pathname actually changes (or on first load when + // previousLocation is null). Avoids double-firing on query/hash-only + // updates. + if ( + previousLocation && + previousLocation.pathname === location.pathname + ) { + return; + } + trackDocsVisited(); }