Skip to content

站点统计

了解如何为 VitePress 站点添加访问统计和分析功能。

Google Analytics

配置 GA4

ts
// docs/.vitepress/config.mts
export default defineConfig({
  head: [
    [
      'script',
      { async: '', src: 'https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX' }
    ],
    [
      'script',
      {},
      `window.dataLayer = window.dataLayer || [];
      function gtag(){dataLayer.push(arguments);}
      gtag('js', new Date());
      gtag('config', 'G-XXXXXXXXXX');`
    ]
  ]
})

获取测量 ID

  1. 访问 Google Analytics
  2. 创建 GA4 媒体资源
  3. 获取测量 ID(格式:G-XXXXXXXXXX)

百度统计

配置

ts
export default defineConfig({
  head: [
    [
      'script',
      {},
      `var _hmt = _hmt || [];
      (function() {
        var hm = document.createElement("script");
        hm.src = "https://hm.baidu.com/hm.js?YOUR_SITE_ID";
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(hm, s);
      })();`
    ]
  ]
})

Cloudflare Analytics

配置

ts
export default defineConfig({
  head: [
    [
      'script',
      { defer: '', src: 'https://static.cloudflareinsights.com/beacon.min.js', 'data-cf-beacon': '{"token": "YOUR_TOKEN"}' }
    ]
  ]
})

Plausible Analytics

开源、隐私友好的分析方案。

配置

ts
export default defineConfig({
  head: [
    [
      'script',
      { defer: '', 'data-domain': 'your-domain.com', src: 'https://plausible.io/js/script.js' }
    ]
  ]
})

Umami

自托管的开源分析方案。

配置

ts
export default defineConfig({
  head: [
    [
      'script',
      { async: '', src: 'https://your-umami.com/script.js', 'data-website-id': 'YOUR_WEBSITE_ID' }
    ]
  ]
})

自定义统计组件

页面浏览统计

vue
<!-- docs/.vitepress/theme/components/Analytics.vue -->
<script setup>
import { onMounted, watch } from 'vue'
import { useRoute } from 'vitepress'

const route = useRoute()

function trackPageView() {
  // 发送页面浏览事件
  if (typeof window !== 'undefined' && window.gtag) {
    window.gtag('event', 'page_view', {
      page_path: route.path,
      page_title: document.title
    })
  }
}

onMounted(() => {
  trackPageView()
})

watch(() => route.path, () => {
  trackPageView()
})
</script>

<template>
  <!-- 无需渲染内容 -->
</template>

注册组件

ts
import DefaultTheme from 'vitepress/theme'
import Analytics from './components/Analytics.vue'

export default {
  extends: DefaultTheme,
  Layout: () => {
    return h(DefaultTheme.Layout, null, {
      'layout-bottom': () => h(Analytics)
    })
  }
}

阅读时间统计

vue
<script setup>
import { ref, onMounted } from 'vue'

const readingTime = ref(0)

function calculateReadingTime() {
  const text = document.querySelector('.vp-doc')?.textContent || ''
  const wordsPerMinute = 200
  const words = text.trim().split(/\s+/).length
  readingTime.value = Math.ceil(words / wordsPerMinute)
}

onMounted(() => {
  calculateReadingTime()
})
</script>

<template>
  <span class="reading-time">阅读时间: {{ readingTime }} 分钟</span>
</template>

访问计数

使用访问计数 API

vue
<script setup>
import { ref, onMounted } from 'vue'
import { useData } from 'vitepress'

const { page } = useData()
const views = ref(0)

onMounted(async () => {
  try {
    const res = await fetch(`https://api.example.com/views?url=${page.value.relativePath}`)
    const data = await res.json()
    views.value = data.views
  } catch (e) {
    console.error('获取访问量失败')
  }
})
</script>

<template>
  <span class="views">阅读 {{ views }} 次</span>
</template>

隐私合规

vue
<!-- docs/.vitepress/theme/components/CookieConsent.vue -->
<script setup>
import { ref, onMounted } from 'vue'

const showConsent = ref(false)
const consent = ref(localStorage.getItem('cookie-consent'))

onMounted(() => {
  if (!consent.value) {
    showConsent.value = true
  }
})

function accept() {
  localStorage.setItem('cookie-consent', 'accepted')
  showConsent.value = false
  // 启用统计脚本
}

function decline() {
  localStorage.setItem('cookie-consent', 'declined')
  showConsent.value = false
}
</script>

<template>
  <div v-if="showConsent" class="cookie-consent">
    <p>
      本网站使用 Cookie 来改善您的体验并提供个性化的内容。
      继续使用本网站即表示您同意我们的 Cookie 政策。
    </p>
    <div class="buttons">
      <button @click="accept">接受</button>
      <button @click="decline">拒绝</button>
    </div>
  </div>
</template>

<style>
.cookie-consent {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background: var(--vp-c-bg);
  padding: 16px 24px;
  border-top: 1px solid var(--vp-c-divider);
  display: flex;
  justify-content: space-between;
  align-items: center;
  z-index: 100;
}

.buttons {
  display: flex;
  gap: 8px;
}
</style>

统计方案对比

方案类型特点
Google Analytics第三方功能全面,免费
百度统计第三方国内访问快
Cloudflare第三方免费,隐私友好
Plausible第三方/自托管开源,隐私友好
Umami自托管开源,完全控制

最佳实践

  1. 选择合适方案:根据需求和隐私要求选择
  2. 遵守法规:GDPR、CCPA 等
  3. 添加同意机制:让用户选择是否被追踪
  4. 定期检查数据:分析访问数据优化内容
  5. 保护用户隐私:不收集敏感信息

下一步

学习 RSS 与站点地图 为站点添加订阅功能。

贡献者

加载中...

想要成为贡献者?

在 CNB 上参与贡献