From 8baa5f9db574e4799c29c703e5423c00b9b6e760 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=7BAI=7Df=20D=2E=20M=C3=BCller?= Date: Tue, 2 Jun 2026 12:28:19 +0200 Subject: [PATCH] fix(analytics): attribute referrer to the entry page only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit document.referrer is fixed for the whole SPA session, so every in-app pageview we send (#562/#565) re-credited the entry referrer — e.g. a single visitor arriving from heise and browsing 20 anchors made heise's referrer list show all 20 paths. Report the referrer only on the initial load (handled by count.js); client-side route changes now send an empty referrer via a callback. External referrers are credited to the landing page only, matching the intuitive "where did this visit come from" meaning. Verified with GoatCounter's get_data: with document.referrer = heise, the landing keeps r="https://www.heise.de" while an SPA anchor view yields r="". Co-Authored-By: Claude Opus 4.8 (1M context) --- website/src/utils/router.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/website/src/utils/router.js b/website/src/utils/router.js index c2b9c35..1868286 100644 --- a/website/src/utils/router.js +++ b/website/src/utils/router.js @@ -155,7 +155,18 @@ function trackPageview() { } const gc = typeof window !== 'undefined' ? window.goatcounter : null if (gc && typeof gc.count === 'function') { - gc.count({ path: window.location.pathname, title: document.title }) + gc.count({ + path: window.location.pathname, + title: document.title, + // Report the referrer only on the initial load (handled by count.js). + // document.referrer is fixed for the whole SPA session, so without this + // every in-app view would be re-credited to the entry referrer (e.g. + // heise), inflating that referrer's page list. A callback returning '' + // drops the referrer for client-side navigations. + referrer: function () { + return '' + }, + }) } }