为 SvelteKit 应用添加隐私优先分析
SvelteKit 2 与其他框架的客户端导航拦截方式不同。这里是无需 cookie 或同意横幅即可追踪路由变化的正确方式。
SvelteKit 2 会破坏那些把测量挂在页面生命周期上的分析集成。普通的 <script> 标签只在文档首次加载时触发一次,之后再也不会——因此其后的每一次客户端导航都是不可见的。Monoid 追踪器通过观察 History API 而非页面生命周期来避开这个问题。
为何普通的 script 标签不够用
<svelte:head> 中的 <script> 标签每次文档加载只执行一次。SvelteKit 2 的路由器就地替换内容而不卸载文档,因此没有任何东西会重新执行它。任何仅以 DOMContentLoaded 或 load 为触发条件的追踪器,都只会上报入口路由,之后便沉默。
这是广泛报道的 Google Analytics GA4 在 SvelteKit 2 应用中仅记录首次加载 pageview 问题的根本原因。
答案是检测导航本身,而这并不需要针对 SvelteKit 的专门集成。SvelteKit 的客户端路由器正是通过调用 history.pushState 来更新 URL,因此给 history.pushState 打补丁的追踪器无需订阅 $app/navigation 或任何框架钩子,就能观察到每一次客户端路由变化。
正确的方法
通过 <svelte:head> 将 Monoid 追踪器脚本一次性添加到你的根 +layout.svelte:
<svelte:head>
<script
async
src="https://api.monoid.website/tracker.min.js"
data-site-id="YOUR_SITE_ID"
></script>
</svelte:head>
追踪器的 DOMContentLoaded 监听器覆盖初始页面加载。对于后续的客户端导航,它对 history.pushState 的补丁会在 SvelteKit 更新 URL 之后立即运行,因此会读取新的 location.pathname 并为每次路由变化发送一次页面浏览。
需要知道的一个限制:该补丁覆盖 pushState,但不覆盖 popstate。后退和前进按钮会在不调用 pushState 的情况下改变路由,因此目前不会产生新的页面浏览。
要验证,请在 DevTools 中打开网络选项卡并观察到 /collect 的 POST 请求。每次路由变化应该看到一次。
区分暂存流量
SvelteKit 项目通常在开发期间运行于 localhost。注册一个单独的站点并将其 site_id 绑定到环境变量,确保开发流量永不污染生产指标:
<script>
const siteId = import.meta.env.VITE_MONOID_SITE_ID
</script>
<svelte:head>
{#if siteId}
<script
async
src="https://api.monoid.website/tracker.min.js"
data-site-id={siteId}
></script>
{/if}
</svelte:head>
在 .env.local 中为开发设置 VITE_MONOID_SITE_ID(或保持未设置以抑制追踪),并在部署环境中为生产设置。{#if siteId} 块确保在变量未设置时追踪器永不注入。
你不需要的东西
无需 cookie 同意横幅。无需更新 cookie 政策。无需检查 navigator.cookieEnabled。收集端点从 IP 地址、User-Agent、服务器端密钥和当前日期派生每日访客哈希:
visitor_hash = SHA-256(IP + UA + SALT_SECRET + YYYY-MM-DD)
哈希每 24 小时重置一次,且无法被反向还原为 IP 或 User-Agent。访客的设备上不存储任何内容。这意味着该集成不触发 ePrivacy 或 PECR 同意要求——没有什么需要同意。
在仪表板中验证
部署后,打开你的分析仪表板并在你的实时站点上的多个路由间导航。每次导航应该产生一个具有正确路径的新 pageview 条目。如果无论导航如何都只看到一个条目,请检查脚本是否在根布局中加载,以及 VITE_MONOID_SITE_ID 是否在生产环境中设置。
你使用的 SvelteKit 适配器(Cloudflare、Vercel、Node、静态)不会影响分析收集,因为追踪完全在水合后于浏览器中进行。
Comments
Loading comments…