Anton Bulakh
2025-02-27 6d350500f1bdadc9604ece5980dafa02150dd849
fix(goatcounter): properly count SPA page hits (#1718)

On the surface it seems that only google and plausible scripts handle
the SPA correctly - but I don't know if maybe others handle
window.history API themselves somehow or something like that.

However, I am trying out goatcounter and in it's docs I see that it
does no special SPA handling, so this has to be fixed.

Just doing the dynamic script thing on every nav seems to do the trick.
The script is not "spa-preserve" so they wouldn't accumulate - and when
I tried the "spa-preserve" + call goatcounter api route it didn't quite
work, they actually did accumulate
1 files modified
14 ■■■■■ changed files
quartz/plugins/emitters/componentResources.ts 14 ●●●●● patch | view | raw | blame | history
quartz/plugins/emitters/componentResources.ts
@@ -122,12 +122,14 @@
    `)
  } else if (cfg.analytics?.provider === "goatcounter") {
    componentResources.afterDOMLoaded.push(`
      const goatcounterScript = document.createElement("script")
      goatcounterScript.src = "${cfg.analytics.scriptSrc ?? "https://gc.zgo.at/count.js"}"
      goatcounterScript.async = true
      goatcounterScript.setAttribute("data-goatcounter",
        "https://${cfg.analytics.websiteId}.${cfg.analytics.host ?? "goatcounter.com"}/count")
      document.head.appendChild(goatcounterScript)
      document.addEventListener("nav", () => {
        const goatcounterScript = document.createElement("script")
        goatcounterScript.src = "${cfg.analytics.scriptSrc ?? "https://gc.zgo.at/count.js"}"
        goatcounterScript.async = true
        goatcounterScript.setAttribute("data-goatcounter",
          "https://${cfg.analytics.websiteId}.${cfg.analytics.host ?? "goatcounter.com"}/count")
        document.head.appendChild(goatcounterScript)
      })
    `)
  } else if (cfg.analytics?.provider === "posthog") {
    componentResources.afterDOMLoaded.push(`