主题
为你的 VitePress 站点选择合适的评论系统,增强用户互动和内容反馈。
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 云开发]
基于 GitHub Discussions,完全免费,适合技术博客和开源项目。
进入仓库 Settings > Features,勾选 Discussions。
Settings > Features
Discussions
访问 giscus.app/zh-CN,填写仓库信息自动生成配置。
<!-- 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>
// 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) } }
<!-- 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>
简单、安全的评论系统,国内访问快速,功能完善。
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
npm install @waline/client
<!-- 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 进入管理后台:
https://your-waline.vercel.app/ui
轻量级评论系统,支持腾讯云开发零成本部署。
envId
# 或使用 CLI 部署 npm install tkserver npx tkserver deploy --envId your-env-id
MONGODB_URI
npm install twikoo
<!-- 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>
基于 GitHub Issues 的轻量评论系统,适合开源项目。
<!-- 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>
<!-- 条件渲染评论组件 --> <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 中禁用评论:
--- title: 关于页面 comments: false ---
Waline 配置:
# 服务端环境变量 AKISMET_KEY=your-akismet-key # Akismet 反垃圾 TURING_TEST=true # 图灵测试 FORBIDDEN_WORDS=违规词1,违规词2 # 敏感词过滤
Twikoo 配置:
// 云函数配置 const config = { AKISMET_KEY: 'your-key', SCF_RECAPTCHA_TOKEN: 'your-token', FORBIDDEN_WORDS: ['违规词1', '违规词2'] }
/* 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; }
Waline 兼容 Valine 数据,只需修改前端配置:
// 旧配置(Valine) new Valine({ appId: 'xxx', appKey: 'xxx' }) // 新配置(Waline) init({ serverURL: 'https://your-waline.vercel.app' })
Giscus 和 Utterances 都基于 GitHub,但 Giscus 功能更强:
data-repo-id
data-category-id
检查 SMTP 配置:
SMTP_SERVICE=QQ SMTP_USER=your@qq.com SMTP_PASS=授权码 SITE_NAME=你的站点名 SITE_URL=https://your-site.com AUTHOR_EMAIL=你的邮箱
在云开发控制台将函数超时时间调整为 10 秒以上:
超时时间: 10s 内存: 256MB
// 使用懒加载,只在评论区域进入视口时加载 onMounted(() => { const observer = new IntersectionObserver((entries) => { if (entries[0].isIntersecting) { loadComments() observer.disconnect() } }) observer.observe(commentContainer.value!) })
每种评论系统的更深度配置(自定义组件开发、评论数据同步、CI/CD 自动化等),请参考:
想要成为贡献者?
评论系统
为你的 VitePress 站点选择合适的评论系统,增强用户互动和内容反馈。
方案对比
选择建议
决策流程
2
3
4
5
6
7
8
9
10
推荐场景
Giscus 配置
基于 GitHub Discussions,完全免费,适合技术博客和开源项目。
前置条件
启用 Discussions
进入仓库
Settings > Features,勾选Discussions。自动配置
访问 giscus.app/zh-CN,填写仓库信息自动生成配置。
创建 Vue 组件
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
注册组件
2
3
4
5
6
7
8
9
10
在布局中使用
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Waline 配置
简单、安全的评论系统,国内访问快速,功能完善。
部署方案
方案一:Vercel + LeanCloud(推荐新手)
方案二:Docker 独立部署(适合有服务器的场景)
2
3
4
5
6
7
8
方案三:Railway 部署
VitePress 集成
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
管理后台
访问
https://your-waline.vercel.app/ui进入管理后台:Twikoo 配置
轻量级评论系统,支持腾讯云开发零成本部署。
部署方案
方案一:腾讯云开发(免费,推荐)
envId2
3
方案二:Vercel + MongoDB
MONGODB_URIVitePress 集成
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Utterances 配置
基于 GitHub Issues 的轻量评论系统,适合开源项目。
前置条件
集成方式
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
进阶配置
仅特定页面显示评论
2
3
4
5
6
7
8
9
10
11
在 frontmatter 中禁用评论:
2
3
4
评论通知
反垃圾策略
Waline 配置:
2
3
4
Twikoo 配置:
2
3
4
5
6
自定义评论样式
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
迁移指南
从 Valine 迁移到 Waline
Waline 兼容 Valine 数据,只需修改前端配置:
2
3
4
5
从 Disqus 迁移
从 Utterances 迁移到 Giscus
Giscus 和 Utterances 都基于 GitHub,但 Giscus 功能更强:
常见问题
Giscus 评论不显示?
data-repo-id和data-category-id正确Waline 邮件发送失败?
检查 SMTP 配置:
2
3
4
5
6
Twikoo 云函数超时?
在云开发控制台将函数超时时间调整为 10 秒以上:
2
评论加载影响页面性能?
2
3
4
5
6
7
8
9
10
进阶内容
每种评论系统的更深度配置(自定义组件开发、评论数据同步、CI/CD 自动化等),请参考:
相关链接