在构建个人静态网站时,了解访客数据是一项基础需求。虽然 Google Analytics 功能强大,但对于追求隐私保护、轻量化和极简主义的开发者来说,GoatCounter 是一个更完美的选择。

GoatCounter 不仅提供了详尽的后台统计,还允许我们以多种方式将访问量显示在页面上。本文将详细介绍三种实现个性化访客计数的方法,从零代码到深度自定义。

方法一:最简单快捷的 SVG 图像法

如果你不想编写任何 JavaScript,或者希望在 Markdown 文件中直接显示访问量,SVG 图像法是最佳选择。GoatCounter 提供了一个动态生成的图片链接。

实现方式

你只需要在 HTML 或 Markdown 中插入一个 <img> 标签:

<!-- 替换 [your-code] 为你的 GoatCounter 站点代码 -->
<img src="https://[your-code].goatcounter.com/counter/TOTAL.svg" alt="Total Views">

实际效果演示

下面是本站真实的 SVG 计数器预览(实时拉取):

Realtime Total Views

特点

  • 优点:零代码实现,支持缓存。
  • 缺点:样式固定(虽然支持一些参数调整,但不够灵活),无法完全融入文本。

方法二:轻量灵活的 JavaScript 钩子法

如果你已经在页面中引入了 GoatCounter 的统计脚本 count.js,可以利用它内置的 visit_count 选项。

实现方式

在你的 count.js 脚本配置中添加 on_load 钩子:

<script data-goatcounter="https://[your-code].goatcounter.com/count"
        async src="//gc.zgo.at/count.js"></script>

<script>
    window.goatcounter = {
        on_load: function() {
            // 当脚本加载完成后,会自动调用此函数
            // 你可以在这里处理显示逻辑
        }
    }
</script>

<!-- 在你希望显示数字的地方 -->
本站总访问量:<span id="demo-hook-count" style="color: #38bdf8; font-weight: bold;">0</span>

实际效果演示

这种方法能够让数字完美融入你的 UI 逻辑。例如,你可以配合 CSS 动画让数字在加载时跳动,或者将其放置在任何复杂的组件内部。

全站总访问量:正在加载…

提示:本站页脚(Footer)中的“全站总访问量”即采用了类似逻辑。


方法三:完全自定义的 JSON API 法

如果你希望计数器的数字就像站点原生的文字一样,没有任何外部样式干扰,且希望完全控制加载逻辑,那么直接调用 JSON API 是最佳方案。

  1. 完全掌控 UI:计数器的数字就像站点原生的文字一样,没有任何外部样式干扰。
  2. 无品牌植入:不显示“by GoatCounter”字样,保持极致简约。
  3. 零依赖:不需要引入额外的库,仅使用原生 JavaScript。

那么,直接调用 JSON API 是最佳方案。

JSON API 核心实现步骤

1. 准确获取页面路径

这是最关键的一步。由于静态站点的 URL 可能带有 .html 后缀,也可能省略,或者末尾带有斜杠。为了确保 API 请求的路径与后台记录的一致,我们利用 GoatCounter 脚本内置的方法。

同时,为了应对子目录部署(如 GitHub Pages)和字符编码问题,我们需要对路径进行适当的清洗:

// 1. 获取规范化路径 'p'
// 2. decodeURIComponent 避免二次编码问题
// 3. 移除可能的项目名称前缀
var path = decodeURIComponent(window.goatcounter.get_data()['p'])
           .replace(/^\/My-Site/, '');

2. 获取单篇文章访问量

_layouts/post.html 中,我们添加一段轻量的脚本:

window.addEventListener('load', function() {
    if (!window.goatcounter || !window.goatcounter.get_data) return;
    
    var path = decodeURIComponent(window.goatcounter.get_data()['p'])
               .replace(/^\/My-Site/, '');
    var r = new XMLHttpRequest();
    
    r.addEventListener('load', function() {
        if (this.status === 200) {
            try {
                var data = JSON.parse(this.responseText);
                document.querySelector('#stats-view-count').innerText = data.count || "0";
            } catch (e) {
                document.querySelector('#stats-view-count').innerText = "0";
            }
        } else {
            // 处理 404 等情况(如新页面尚未产生数据)
            document.querySelector('#stats-view-count').innerText = "0";
        }
    });
    
    r.open('GET', 'https://[your-code].goatcounter.com/counter/' + encodeURIComponent(path) + '.json');
    r.send();
});

3. 获取全站总访问量

全站总计可以通过一个特殊的路径 TOTAL 来获取。我们通常将其放在 _includes/footer.html 中:

r.open('GET', 'https://[your-code].goatcounter.com/counter/TOTAL.json');
r.send();

实际效果演示(本文实时数据)

通过 JSON API,我们可以直接在正文中插入当前的阅读量。这种方式不需要 count.js 脚本运行,而是直接通过前端请求拉取数据。

本文阅读次数:正在加载…

样式处理

由于我们只是将获取到的数字填充到 HTML 的 <span> 标签中,因此它会自动继承该位置的 CSS 样式(字体、颜色、字号等)。

#stats-total-count {
  color: #38bdf8; /* 站点主题蓝 */
  font-weight: 600;
}

方法四:服务端 API 计数法 (GoatCounter API v0)

如果你需要在后端服务(如 Node.js, Go, Python)中记录事件,或者希望在命令行工具中集成统计,GoatCounter 的 API v0 提供了直接提交点击数据的功能。

实现方式

API v0 不仅支持记录访问,还支持查询、导出和管理。以下是核心接口参考:

动作 端点 说明
POST /api/v0/count 统计页面浏览量(支持批量)
GET /api/v0/stats/total 获取站点全站浏览总数
GET /api/v0/me 获取当前 Token 所属用户信息
GET /api/v0/paths 获取所有已记录的路径列表
POST /api/v0/export 创建一个新的 CSV 导出文件

Bash 示例:

# 使用你的 API Token 进行身份验证
token="1lf3lupfunccb7awges6d8v96pgprwubf38je1zgle0yw67w6c"
api="https://way.goatcounter.com/api/v0"

# 发送点击数据
curl -X POST "$api/count" \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer $token" \
    --data '{"no_sessions": true, "hits": [{"path": "/one"}]}'

# 导出 CSV 数据
id=$(curl -X POST "$api/export" -H "Authorization: Bearer $token" | jq .id)

速率限制: API 限制为每秒 4 个请求。错误信息会通过 errorerrors 字段返回。

实际效果演示 (API 实验室)

点击下方按钮,我们将执行一系列 API 调用:首先为本文路径提交一个统计点击(这有助于修复方法三的 404 状态),然后实时拉取您的账户信息和全站统计指标。

等待启动...


四种方法对比

特性 SVG 图像法 JS 钩子法 JSON API 法 API v0 (后端)
实现难度 极低 中等 进阶
自定义程度 中等 极高 深度定制
依赖项 count.js 原生 JS API Token
适用场景 Markdown 预览 快速集成 主题深度定制 后端、命令行

总结

无论你是追求极致简便还是完美定制,GoatCounter 都能满足需求。通过 JSON API,我们不仅保护了访客隐私,还保持了网站的加载性能。整个计数逻辑在页面加载完成后异步执行,不会阻塞页面渲染,同时也为站点增添了一份动态的生命力。

... 次阅读