Skip to content

评论系统

为你的 VitePress 站点选择合适的评论系统,增强用户互动和内容反馈。

方案对比

特性GiscusWalineTwikooDisqusUtterances
类型GitHub Discussions自托管/云服务自托管/云服务云服务GitHub Issues
数据存储GitHub数据库数据库云端GitHub Issues
免费✅ 完全免费✅ 有免费额度✅ 有免费额度⚠️ 有广告✅ 完全免费
国内访问⚠️ 需代理✅ 快速✅ 快速❌ 较慢⚠️ 需代理
登录方式GitHub多种多种Disqus/社交GitHub
邮件通知
管理后台GitHubGitHub
匿名评论
部署难度⭐ 简单⭐⭐ 中等⭐⭐ 中等⭐ 简单⭐ 简单
暗色模式✅ 自动跟随✅ 支持✅ 支持⚠️ 需配置✅ 支持

选择建议

决策流程

mermaid
graph TD
    A[选择评论系统] --> B{是否需要免费?}
    B -->|是| C{主要访问者在哪里?}
    B -->|否| D[Disqus]
    C -->|国内| E{是否有服务器?}
    C -->|国外| F{需要匿名评论?}
    F -->|否| G[Giscus]
    F -->|是| H[Waline]
    E -->|是| I[Waline/Twikoo]
    E -->|否| J[Twikoo 云开发]

推荐场景

场景推荐原因
技术博客GiscusGitHub 用户友好,免费无限制
个人博客Waline功能完整,国内访问快
小型站点Twikoo部署简单,轻量级
国际站点Disqus用户基数大,但国内访问差
开源项目文档Utterances基于 GitHub Issues,与项目关联

Giscus 配置

基于 GitHub Discussions,完全免费,适合技术博客和开源项目。

前置条件

  1. GitHub 仓库必须 公开
  2. 已安装 giscus app
  3. 仓库已启用 Discussions 功能

启用 Discussions

进入仓库 Settings > Features,勾选 Discussions

自动配置

访问 giscus.app/zh-CN,填写仓库信息自动生成配置。

创建 Vue 组件

vue
<!-- docs/.vitepress/components/GiscusComments.vue -->
<script setup lang="ts">
import { useData } from 'vitepress'
import { watch, onMounted, ref } from 'vue'

const { isDark } = useData()
const giscusRef = ref<HTMLElement>()

const giscusConfig = {
  repo: 'your-username/your-repo',
  repoId: 'R_xxxxx',
  category: 'Announcements',
  categoryId: 'DIC_xxxxx',
  mapping: 'pathname' as const,
  reactionsEnabled: '1',
  inputPosition: 'top' as const,
  lang: 'zh-CN'
}

onMounted(() => {
  loadGiscus()
})

watch(isDark, () => {
  // 通知 Giscus 切换主题
  const iframe = giscusRef.value?.querySelector('iframe')
  if (iframe) {
    iframe.contentWindow?.postMessage(
      { giscus: { setConfig: { theme: isDark.value ? 'dark' : 'light' } } },
      'https://giscus.app'
    )
  }
})

function loadGiscus() {
  const script = document.createElement('script')
  script.src = 'https://giscus.app/client.js'
  script.setAttribute('data-repo', giscusConfig.repo)
  script.setAttribute('data-repo-id', giscusConfig.repoId)
  script.setAttribute('data-category', giscusConfig.category)
  script.setAttribute('data-category-id', giscusConfig.categoryId)
  script.setAttribute('data-mapping', giscusConfig.mapping)
  script.setAttribute('data-reactions-enabled', giscusConfig.reactionsEnabled)
  script.setAttribute('data-input-position', giscusConfig.inputPosition)
  script.setAttribute('data-theme', isDark.value ? 'dark' : 'light')
  script.setAttribute('data-lang', giscusConfig.lang)
  script.setAttribute('crossorigin', 'anonymous')
  script.async = true
  giscusRef.value?.appendChild(script)
}
</script>

<template>
  <div class="giscus-container">
    <div ref="giscusRef" class="giscus" />
  </div>
</template>

<style scoped>
.giscus-container {
  margin-top: 2rem;
  padding-top: 1rem;
  border-top: 1px solid var(--vp-c-divider);
}
</style>

注册组件

ts
// docs/.vitepress/theme/index.ts
import DefaultTheme from 'vitepress/theme'
import GiscusComments from './components/GiscusComments.vue'

export default {
  extends: DefaultTheme,
  enhanceApp({ app }) {
    app.component('GiscusComments', GiscusComments)
  }
}

在布局中使用

vue
<!-- docs/.vitepress/theme/Layout.vue -->
<script setup lang="ts">
import DefaultTheme from 'vitepress/theme'
import GiscusComments from './components/GiscusComments.vue'

const { Layout } = DefaultTheme
</script>

<template>
  <Layout>
    <template #doc-after>
      <GiscusComments />
    </template>
  </Layout>
</template>

Waline 配置

简单、安全的评论系统,国内访问快速,功能完善。

部署方案

方案一:Vercel + LeanCloud(推荐新手)

  1. 注册 LeanCloud 国际版,创建应用
  2. 获取 AppID、AppKey、MasterKey
  3. 一键部署到 Vercel:Waline Vercel 部署
  4. 设置环境变量:
变量名
LEAN_IDLeanCloud AppID
LEAN_KEYLeanCloud AppKey
LEAN_MASTER_KEYLeanCloud MasterKey

方案二:Docker 独立部署(适合有服务器的场景)

bash
docker run -d \
  --name waline \
  -p 8360:8360 \
  -e MYSQL_HOST=db_host \
  -e MYSQL_DB=waline \
  -e MYSQL_USER=waline \
  -e MYSQL_PASSWORD=password \
  lizheming/waline

方案三:Railway 部署

  1. Fork Waline 仓库
  2. Railway 中导入
  3. 添加 PostgreSQL 插件
  4. 自动部署完成

VitePress 集成

bash
npm install @waline/client
vue
<!-- docs/.vitepress/components/WalineComments.vue -->
<script setup lang="ts">
import { useData } from 'vitepress'
import { init } from '@waline/client'
import { onMounted, watch, ref } from 'vue'

import '@waline/client/style'

const { isDark } = useData()
const walineRef = ref<HTMLElement>()

const walineUrl = 'https://your-waline.vercel.app'

let waline: ReturnType<typeof init> | null = null

onMounted(() => {
  waline = init({
    el: walineRef.value!,
    serverURL: walineUrl,
    lang: 'zh-CN',
    dark: 'html.dark',
    login: 'enable',
    meta: ['nick', 'mail', 'link'],
    requiredMeta: ['nick', 'mail'],
    pageSize: 10,
    imageUploader: false,
    highlighter: false
  })
})

watch(isDark, () => {
  // Waline 通过 dark 选项自动响应主题
  waline?.update({ dark: isDark.value ? 'html.dark' : '' })
})
</script>

<template>
  <div class="waline-container">
    <div ref="walineRef" />
  </div>
</template>

<style scoped>
.waline-container {
  margin-top: 2rem;
  padding-top: 1rem;
  border-top: 1px solid var(--vp-c-divider);
}
</style>

管理后台

访问 https://your-waline.vercel.app/ui 进入管理后台:

  • 评论审核:自动/手动审核评论
  • 用户管理:查看和管理评论用户
  • 邮件通知:配置 SMTP 发送通知邮件
  • 垃圾过滤:Akismet 反垃圾集成

Twikoo 配置

轻量级评论系统,支持腾讯云开发零成本部署。

部署方案

方案一:腾讯云开发(免费,推荐)

  1. 开通 腾讯云开发
  2. 创建环境,记录环境 ID envId
  3. 在「云函数」中创建函数,选择「Twikoo」
bash
# 或使用 CLI 部署
npm install tkserver
npx tkserver deploy --envId your-env-id

方案二:Vercel + MongoDB

  1. 准备 MongoDB 数据库(推荐 MongoDB Atlas 免费版)
  2. 一键部署:Twikoo Vercel
  3. 设置环境变量 MONGODB_URI

VitePress 集成

bash
npm install twikoo
vue
<!-- docs/.vitepress/components/TwikooComments.vue -->
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { useData } from 'vitepress'

const { isDark } = useData()
const twikooEnvId = 'your-twikoo-env-id'

onMounted(async () => {
  const twikoo = await import('twikoo')
  twikoo.init({
    envId: twikooEnvId,
    el: '#twikoo-comment',
    lang: 'zh-CN'
  })
})
</script>

<template>
  <div class="twikoo-container">
    <div id="twikoo-comment" />
  </div>
</template>

<style scoped>
.twikoo-container {
  margin-top: 2rem;
  padding-top: 1rem;
  border-top: 1px solid var(--vp-c-divider);
}
</style>

Utterances 配置

基于 GitHub Issues 的轻量评论系统,适合开源项目。

前置条件

  1. GitHub 仓库公开
  2. 安装 utterances app

集成方式

vue
<!-- docs/.vitepress/components/UtterancesComments.vue -->
<script setup lang="ts">
import { useData } from 'vitepress'
import { onMounted, ref } from 'vue'

const { isDark } = useData()
const utterancesRef = ref<HTMLElement>()

onMounted(() => {
  const script = document.createElement('script')
  script.src = 'https://utteranc.es/client.js'
  script.setAttribute('repo', 'your-username/your-repo')
  script.setAttribute('issue-term', 'pathname')
  script.setAttribute('theme', isDark.value ? 'github-dark' : 'github-light')
  script.setAttribute('crossorigin', 'anonymous')
  script.async = true
  utterancesRef.value?.appendChild(script)
})
</script>

<template>
  <div class="utterances-container">
    <div ref="utterancesRef" />
  </div>
</template>

<style scoped>
.utterances-container {
  margin-top: 2rem;
  padding-top: 1rem;
  border-top: 1px solid var(--vp-c-divider);
}
</style>

进阶配置

仅特定页面显示评论

vue
<!-- 条件渲染评论组件 -->
<script setup lang="ts">
import { useData } from 'vitepress'
import GiscusComments from './GiscusComments.vue'

const { frontmatter } = useData()
</script>

<template>
  <GiscusComments v-if="frontmatter.comments !== false" />
</template>

在 frontmatter 中禁用评论:

yaml
---
title: 关于页面
comments: false
---

评论通知

系统邮件微信TelegramQQ
GiscusGitHub 通知
Waline✅ SMTP✅ Server酱✅ Bot
Twikoo✅ SMTP✅ Server酱✅ Bot✅ Qmsg

反垃圾策略

Waline 配置:

env
# 服务端环境变量
AKISMET_KEY=your-akismet-key    # Akismet 反垃圾
TURING_TEST=true                # 图灵测试
FORBIDDEN_WORDS=违规词1,违规词2  # 敏感词过滤

Twikoo 配置:

js
// 云函数配置
const config = {
  AKISMET_KEY: 'your-key',
  SCF_RECAPTCHA_TOKEN: 'your-token',
  FORBIDDEN_WORDS: ['违规词1', '违规词2']
}

自定义评论样式

css
/* Waline 自定义样式 */
.waline-container {
  --waline-theme-color: var(--vp-c-brand-1);
  --waline-active-color: var(--vp-c-brand-2);
  --waline-font-size: 0.95rem;
  --waline-border-color: var(--vp-c-divider);
}

/* Twikoo 自定义样式 */
.twikoo-container .tk-content {
  font-size: 0.95rem;
  line-height: 1.6;
}

/* Giscus 容器样式 */
.giscus-container {
  max-width: 100%;
  margin-top: 2rem;
}

迁移指南

从 Valine 迁移到 Waline

Waline 兼容 Valine 数据,只需修改前端配置:

js
// 旧配置(Valine)
new Valine({ appId: 'xxx', appKey: 'xxx' })

// 新配置(Waline)
init({ serverURL: 'https://your-waline.vercel.app' })

从 Disqus 迁移

  1. 导出 Disqus 评论(XML 格式)
  2. 使用 disqus-to-waline 转换工具
  3. 导入到 Waline 数据库

从 Utterances 迁移到 Giscus

Giscus 和 Utterances 都基于 GitHub,但 Giscus 功能更强:

  1. 安装 giscus app(替代 utterances app)
  2. 启用 Discussions 功能
  3. 修改前端组件配置
  4. 原有 Issues 评论可手动迁移到 Discussions

常见问题

Giscus 评论不显示?

  1. 检查仓库是否 公开
  2. 确认已安装 giscus app
  3. 检查 Discussions 是否启用
  4. 确认 data-repo-iddata-category-id 正确
  5. 浏览器控制台检查是否有跨域错误

Waline 邮件发送失败?

检查 SMTP 配置:

env
SMTP_SERVICE=QQ
SMTP_USER=your@qq.com
SMTP_PASS=授权码
SITE_NAME=你的站点名
SITE_URL=https://your-site.com
AUTHOR_EMAIL=你的邮箱

Twikoo 云函数超时?

在云开发控制台将函数超时时间调整为 10 秒以上:

yaml
超时时间: 10s
内存: 256MB

评论加载影响页面性能?

ts
// 使用懒加载,只在评论区域进入视口时加载
onMounted(() => {
  const observer = new IntersectionObserver((entries) => {
    if (entries[0].isIntersecting) {
      loadComments()
      observer.disconnect()
    }
  })
  observer.observe(commentContainer.value!)
})

进阶内容

每种评论系统的更深度配置(自定义组件开发、评论数据同步、CI/CD 自动化等),请参考:

相关链接

贡献者

加载中...

想要成为贡献者?

在 CNB 上参与贡献