From 9b694a69ab01d783fb601d5cc0926edda959a4b4 Mon Sep 17 00:00:00 2001 From: Marek Honzal Date: Fri, 24 Apr 2026 15:42:32 +0200 Subject: [PATCH 1/2] feat: implement segment link tracking, opt-in solution, track only Apify Trust Center --- .../docusaurus-plugin-segment/index.js | 5 +- .../docusaurus-plugin-segment/linkTracking.js | 59 +++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 src/plugins/docusaurus-plugin-segment/linkTracking.js diff --git a/src/plugins/docusaurus-plugin-segment/index.js b/src/plugins/docusaurus-plugin-segment/index.js index 5ee41b4d36..1642c001f1 100644 --- a/src/plugins/docusaurus-plugin-segment/index.js +++ b/src/plugins/docusaurus-plugin-segment/index.js @@ -7,7 +7,10 @@ module.exports = function (context, options) { name: 'docusaurus-plugin-segment', getClientModules() { - return [path.resolve(__dirname, './segment')]; + return [ + path.resolve(__dirname, './segment'), + path.resolve(__dirname, './linkTracking'), + ]; }, injectHtmlTags() { diff --git a/src/plugins/docusaurus-plugin-segment/linkTracking.js b/src/plugins/docusaurus-plugin-segment/linkTracking.js new file mode 100644 index 0000000000..79491a3d5d --- /dev/null +++ b/src/plugins/docusaurus-plugin-segment/linkTracking.js @@ -0,0 +1,59 @@ +import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment'; + +// Opt-in link trackers. Currently limited to Trust Center to avoid Segment noise - see https://github.com/apify/apify-docs/issues/2409. +const LINK_TRACKERS = [ + { + test: (url) => url.hostname === 'trust.apify.com', + element: 'trust-center-link', + }, + // Examples for future opt-in: + // { test: (url) => !/(^|\.)apify\.com$/.test(url.hostname) } // all outbound + // { test: () => true } // all links +]; + +let installed = false; + +function handleLinkClick(event) { + // auxclick fires for all non-primary buttons; only handle middle click (button === 1) + if (event.type === 'auxclick' && event.button !== 1) return; + if (process.env.NODE_ENV !== 'production' || !window.analytics) return; + + const anchor = event.target.closest('a[href]'); + if (!anchor) return; + + let url; + try { + url = new URL(anchor.getAttribute('href'), window.location.href); + } catch { + return; + } + if (!/^https?:$/.test(url.protocol)) return; + + const tracker = LINK_TRACKERS.find(({ test }) => test(url)); + if (!tracker) return; + + const isApifyDomain = /(^|\.)apify\.com$/.test(url.hostname); + + window.analytics.track('Clicked', { + app: 'docs', + element: tracker.element ?? 'link', + button_text: anchor.textContent?.trim().slice(0, 200) || null, + href: url.href, + is_subdomain: isApifyDomain && url.hostname !== window.location.hostname, + is_outbound: !isApifyDomain, + }); +} + +function installLinkClickTracker() { + if (installed) return; + installed = true; + + document.addEventListener('click', handleLinkClick, { capture: true }); + document.addEventListener('auxclick', handleLinkClick, { capture: true }); +} + +export default ExecutionEnvironment.canUseDOM ? { + onRouteDidUpdate() { + installLinkClickTracker(); + }, +} : null; From ace2071bac4bf332f01b9151a1e97fdd0ffc148a Mon Sep 17 00:00:00 2001 From: Marek Honzal Date: Mon, 27 Apr 2026 13:28:59 +0200 Subject: [PATCH 2/2] feat: add support for data-tracking-id and clarify usage --- .../docusaurus-plugin-segment/linkTracking.js | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/plugins/docusaurus-plugin-segment/linkTracking.js b/src/plugins/docusaurus-plugin-segment/linkTracking.js index 79491a3d5d..29ea4f15b5 100644 --- a/src/plugins/docusaurus-plugin-segment/linkTracking.js +++ b/src/plugins/docusaurus-plugin-segment/linkTracking.js @@ -1,6 +1,16 @@ import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment'; -// Opt-in link trackers. Currently limited to Trust Center to avoid Segment noise - see https://github.com/apify/apify-docs/issues/2409. +/** + * Opt-in link trackers. Currently limited to Trust Center to avoid Segment noise. + * @see https://github.com/apify/apify-docs/issues/2409 + * + * Each entry has a `test(url)` predicate and an `element` label — a human-readable identifier + * for the clicked UI element, sent as the `element` property in the Segment "Clicked" event. + * Individual links can also opt in via a `data-tracking-id` attribute, which takes precedence. + * + * @example + * { test: (url) => url.hostname === 'trust.apify.com', element: 'trust-center-link' } + */ const LINK_TRACKERS = [ { test: (url) => url.hostname === 'trust.apify.com', @@ -30,13 +40,15 @@ function handleLinkClick(event) { if (!/^https?:$/.test(url.protocol)) return; const tracker = LINK_TRACKERS.find(({ test }) => test(url)); - if (!tracker) return; + const dataId = anchor.dataset.trackingId; // reads data-tracking-id attribute + + if (!tracker && !dataId) return; const isApifyDomain = /(^|\.)apify\.com$/.test(url.hostname); window.analytics.track('Clicked', { app: 'docs', - element: tracker.element ?? 'link', + element: dataId ?? tracker?.element ?? 'link', button_text: anchor.textContent?.trim().slice(0, 200) || null, href: url.href, is_subdomain: isApifyDomain && url.hostname !== window.location.hostname,