From 00203c57fcb99c2df9f6f3525347343576e29231 Mon Sep 17 00:00:00 2001 From: JakeSCahill Date: Fri, 17 Jul 2026 13:17:56 +0100 Subject: [PATCH] Lead-gen Group 4: first-party docs-behavior beacon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New signed-in-only pageview beacon. For users with the rp_docs_auth hint cookie, reports one pageview per navigation (path, Antora component, and the search term on /search) to the docs-site /docs-activity endpoint, which records it server-side against the account. Replaces anonymous third-party analytics (Plausible/Heap/Algolia) for lead purposes. Anonymous visitors send nothing. Same-origin (session cookie rides along). Deduped once-per-path-per-tab-session to keep write volume to real navigations. Fire-and-forget; never blocks or throws into the page. Capture only — the endpoint stores to our own user store; nothing is delivered to sales. Co-Authored-By: Claude Opus 4.8 --- src/js/27-docs-activity.js | 50 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 src/js/27-docs-activity.js diff --git a/src/js/27-docs-activity.js b/src/js/27-docs-activity.js new file mode 100644 index 00000000..5f249ebe --- /dev/null +++ b/src/js/27-docs-activity.js @@ -0,0 +1,50 @@ +/* global sessionStorage, fetch */ +/** + * First-party docs-behavior beacon (lead capture). + * + * For SIGNED-IN docs users only (rp_docs_auth hint cookie), reports one + * pageview per navigation to the docs-site /docs-activity endpoint, which + * records it server-side against the user's account. Replaces anonymous + * third-party analytics (Plausible/Heap/Algolia) for lead purposes. + * + * Anonymous visitors send nothing. Same-origin, so the session cookie rides + * along automatically. Fire-and-forget; never blocks or throws into the page. + */ +;(function () { + 'use strict' + + // Only signed-in users are tracked (matches 26-docs-account.js). + if (!/(?:^|;\s*)rp_docs_auth=1(?:;|$)/.test(document.cookie)) return + + var path = window.location.pathname + if (!path) return + + // Beacon once per path per tab session — avoids duplicate writes on + // back/forward and re-renders. Keeps server write volume to real navigations. + try { + var key = 'docs-activity-seen' + var seen = (sessionStorage.getItem(key) || '').split('\n') + if (seen.indexOf(path) !== -1) return + seen.push(path) + sessionStorage.setItem(key, seen.slice(-200).join('\n')) + } catch (e) { /* private mode: proceed without dedupe */ } + + // Antora component (product) exposed by the layout: + var component = (document.body && document.body.getAttribute('data-component')) || null + + // Capture the search term on the standalone /search page (URL-driven). + var q = null + if (path.indexOf('/search') !== -1) { + try { q = new URLSearchParams(window.location.search).get('q') } catch (e) { /* ignore */ } + } + + try { + fetch('/docs-activity', { + method: 'POST', + credentials: 'include', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ path: path, component: component, q: q }), + keepalive: true, + }).catch(function () { /* best-effort */ }) + } catch (e) { /* never break the page */ } +})()