Skip to Main Content
404Back to Top

23 June 2026, 20:00 (CST)

2026年06月23日(东八区)

功能调试:Umami 流量统计未生效

概述

站点启用 Ametrine 主题内置的 Umami 统计后,Umami 控制台 长期无访客数据。本次排查确认根因为 zola.tomlself_hosted_url 误填为博客域名,导致追踪脚本指向不存在的 /script.js,且 CSP 未放行 Umami Cloud 域名。修复后仅改动站点根目录 zola.toml未修改 themes/


1. Umami 在源代码中的设计逻辑与调用链

Ametrine 主题(参考 daudix.one)将统计能力拆为 配置 → CSP 白名单 → 脚本注入 三层,全部在 themes/ametrine/templates/partials/ 中实现。

1.1 配置入口:zola.toml

[extra.analytics]
service = "umami"                                          # 统计服务:goatcounter | umami | plausible
id = "cdf54193-b449-4454-884b-029e82434c32"                # Umami Cloud 的 website ID
# self_hosted_url = "https://stats.example.com"            # 仅自托管 Umami 时填写
exclude_hash = true                                        # 可选:不采集 URL hash
# exclude_search = false                                   # 可选:不采集 URL 查询参数
# do_not_track = false                                     # 可选:尊重浏览器 DNT
字段作用
service选择统计后端,决定加载哪段 partial
idUmami 的 data-website-id
self_hosted_url自托管实例根 URL;留空则走 Umami Cloud(cloud.umami.is
exclude_hash / exclude_search / do_not_track映射为 <script> 上的 data-* 属性

主题默认示例见 themes/ametrine/config.toml[extra.analytics] 段(daudix 使用自托管 https://stats.daudix.one)。

1.2 CSP 白名单:partials/csp.html

页面 <head> 内生成 Content-Security-Policy,决定是否允许加载外部脚本与上报数据:

config.extra.csp(zola.toml 自定义域)

csp.html 合并 analytics 域

<meta http-equiv="Content-Security-Policy" …>

Umami 相关逻辑themes/ametrine/templates/partials/csp.html):

条件script-src 追加connect-src 追加
设置了 self_hosted_url该 URL该 URL
未设置 + service == "umami"cloud.umami.is*.umami.dev cloud.umami.is

若误填 self_hosted_url 为博客地址,CSP 不会自动加入 cloud.umami.is,脚本即使写对也会被策略拦截。

1.3 脚本注入:partials/head.htmlpartials/analytics.html

触发条件themes/ametrine/templates/partials/head.html):

{%- if config.mode != "serve" and config.extra.analytics.service -%}
  {%- include "partials/analytics.html" -%}
{%- endif -%}

要点:

Umami 脚本生成themes/ametrine/templates/partials/analytics.html):

条件输出
self_hosted_url 有值<script … src="{{ self_hosted_url }}/script.js" data-website-id="{{ id }}">
self_hosted_url 为空<script … src="https://cloud.umami.is/script.js" data-website-id="{{ id }}">

等价于官方嵌入代码:

<script defer src="https://cloud.umami.is/script.js"
  data-website-id="cdf54193-b449-4454-884b-029e82434c32"></script>

1.4 完整调用链(生产环境)

zola build
  → head.html 读取 config.extra.analytics
  → csp.html 写入 script-src / connect-src 白名单
  → analytics.html 输出 <script defer src="cloud.umami.is/script.js">
  → 浏览器加载 script.js
  → script.js 向 *.umami.dev / cloud.umami.is 上报 pageview
  → Umami 控制台展示数据

2. 本次错误原因与修复方案

2.1 现象

检查项修复前(线上)
页面 <script>src="https://suchaharcan.github.io/script.js"
脚本 HTTP 状态404(GitHub Pages 无此文件)
CSP script-src'self' https://suchaharcan.github.io … cloud.umami.is
CSP connect-src *.umami.dev
Umami 控制台无访客记录

2.2 根因

复制 daudix.one 配置时,将 self_hosted_url 设成了博客域名 https://suchaharcan.github.io

daudix 的 self_hosted_url = "https://stats.daudix.one" 指向独立的 Umami 自托管实例;本站点使用的是 Umami Cloud,不应填写 self_hosted_url

连锁影响:

  1. 脚本 URL 错误 — 主题从 博客域名/script.js 加载,文件不存在。
  2. CSP 错误 — 白名单指向博客域名,未放行 cloud.umami.is*.umami.dev
  3. 即使手动改 script 地址,上报请求仍会被 CSP 拦截。

2.3 修复

文件zola.toml(仅此一处,未改 themes/

 [extra.analytics]
 service = "umami"
 id = "cdf54193-b449-4454-884b-029e82434c32"
-self_hosted_url = "https://suchaharcan.github.io"
 exclude_hash = true

修复后 zola build 产物对比:

检查项修复后
脚本src="https://cloud.umami.is/script.js"200
CSPscript-src … cloud.umami.isconnect-src … *.umami.dev cloud.umami.is
website IDcdf54193-b449-4454-884b-029e82434c32

部署提醒:本地 build 已正确,需 push 触发 GitHub Pages 重建后线上才生效。


3. 验证方式与使用注意点

3.1 部署后验证(推荐)

  1. 浏览器 Network

    • 打开 https://suchaharcan.github.io/
    • DevTools → Network,筛选 script.js
    • 确认来源为 cloud.umami.is,状态 200
  2. 查看页面源码

    • 搜索 data-website-id,应出现 cdf54193-b449-4454-884b-029e82434c32
    • 搜索 Content-Security-Policy,应含 cloud.umami.is
  3. Umami 控制台

    • 登录 Analytics 面板
    • 刷新博客首页,Realtime / 今日访客应在数秒内更新
  4. 命令行快速检查(可选)

    curl -sL "https://suchaharcan.github.io/" | grep -o 'cloud.umami.is/script.js'
    # 应输出:cloud.umami.is/script.js
    
    curl -sI "https://cloud.umami.is/script.js" | head -1
    # 应输出:HTTP/2 200

3.2 使用注意点

场景说明
zola serve 本地开发不注入 analytics,Network 中看不到 Umami 脚本 — 正常
Umami Cloud vs 自托管Cloud 用户不要self_hosted_url;自托管才填实例根 URL(如 https://stats.example.com
CSP 自定义域zola.toml[extra.csp] 与主题自动合并;Umami Cloud 域由主题在 self_hosted_url 为空时自动追加
参考 daudix.one可借鉴导航、CSP 结构等;self_hosted_url 不能直接照搬(daudix 为自托管)
不修改 themes/统计逻辑已在主题内;站点级只需正确配置 zola.toml 并 build 部署
隐私 / 分享数据分享页:https://cloud.umami.is/share/2hWVbYvlPUkk98Yz
AdBlock / 隐私扩展访客若安装拦截器,可能不上报 — 控制台数据为「可统计访客」子集

3.3 配置对照速查

部署方式serviceidself_hosted_url
Umami Cloud(本站)umamiCloud 控制台 website ID留空
自托管 Umamiumami实例中的 website IDhttps://你的-umami-域名
GoatCounter / Plausible对应 service 名各服务文档自托管时填实例 URL

修改文件

文件变更
zola.toml删除错误的 self_hosted_url = "https://suchaharcan.github.io"

相关链接:Umami 控制台 · 数据分享页 · daudix.one 参考仓库 · 热力图 + 统计启用记录

22 June 2026, 20:00 (CST)