跳到主要内容

giscus 评论组件集成说明

本站是纯静态 Docusaurus 站点,评论能力不能依赖本地服务器或运行时数据库。当前实现使用 giscus,把页面评论存放到独立 GitHub Discussions 仓库 NeverGpDzy/docs-comments,站点只负责在指定页面加载评论组件。

评论组件的设计目标是和音频播放器一样自动挂载:文章作者不需要在每篇 Markdown 或 MDX 文件里手动引入组件。只要页面属于博客详情页、Travel 文档详情页,或被布局层明确允许的自定义页面,布局层会自动渲染评论区。

当前行为

评论只出现在下面这些页面:

页面类型中文路径英文路径是否显示评论
博客详情页/blog/.../en/blog/...
Travel 文档详情页/docs/Travel/.../en/docs/Travel/...
About 页面/about/en/about
博客列表页/blog/en/blog
其他文档页/docs/Travel/... 的文档/en/docs/Travel/... 的文档
其他自定义页面/about 的自定义页面/en/about 的自定义页面

中英文对应页面共用同一条 Discussion。实现方式是把英文页面路径开头的 /en 去掉后再作为 giscus 的 term

/blog/2026/05/02/hamasushi-big-conveyor-belt-sushi-meal
/en/blog/2026/05/02/hamasushi-big-conveyor-belt-sushi-meal
-> /blog/2026/05/02/hamasushi-big-conveyor-belt-sushi-meal

/docs/Travel/hong-kong-travel
/en/docs/Travel/hong-kong-travel
-> /docs/Travel/hong-kong-travel

/about
/en/about
-> /about

这样读者在中文页或英文页看到的是同一个评论区,避免同一篇内容被拆成两套讨论。

GitHub 侧配置

评论数据放在仓库:

NeverGpDzy/docs-comments

这个仓库需要满足以下条件:

  1. 仓库必须是 public。
  2. Settings -> General -> Features 中启用 Discussions。
  3. Discussions 中存在 Announcements 分类。
  4. giscus GitHub App 已安装并授权给 NeverGpDzy/docs-comments
  5. 不创建 giscus.json,因此不限制来源域名。

当前前端写死的 giscus 配置如下:

配置项
repoNeverGpDzy/docs-comments
repoIdR_kgDOSTPzRQ
categoryAnnouncements
categoryIdDIC_kwDOSTPzRc4C8Qej
mappingspecific
strict1
reactionsEnabled1
emitMetadata0
inputPositionbottom
loadinglazy

repoIdcategoryId 不是密钥,可以写入前端代码。它们来自 giscus 配置页生成的 script 片段。

代码结构

核心文件:

文件作用
src/components/GiscusComments/index.js评论组件主体,封装 giscus 配置、语言、主题和 term 生成
src/components/GiscusComments/styles.module.css评论区标题、间距和分隔线样式
src/theme/BlogPostPage/index.js博客详情页 swizzle 布局,自动挂载评论
src/theme/DocItem/Layout/index.js文档详情页 swizzle 布局,仅在 Travel 分支挂载评论
src/theme/MDXPage/index.jscontent-pages 布局,仅在 About 页面挂载评论
package.json声明 @giscus/react 依赖

组件关系:

BlogPostPage
-> BlogAudioPlayer
-> BlogPostItem
-> GiscusComments
-> BlogPostPaginator

DocItem/Layout
-> if isTravelDocMetadata(metadata)
-> DocItemContent
-> GiscusComments
-> DocItemPaginator
-> else
-> normal doc layout without comments

MDXPage
-> MDXContent
-> if getGiscusTerm(metadata.permalink) === '/about'
-> GiscusComments
-> else
-> normal MDX page without comments

评论组件实现

GiscusComments 接收一个可选的 permalink

<GiscusComments permalink={metadata.permalink} />

博客页和文档页都传入 Docusaurus metadata 中的 permalink,而不是直接依赖浏览器地址。这样 SSR、静态构建和客户端导航时使用的路径来源更稳定。

组件内部会处理四件事。

1. 生成稳定的 giscus term

getGiscusTerm() 会规范化路径:

  1. 去掉 #hash
  2. 去掉 ?query
  3. 去掉尾部 /
  4. 如果路径以 /en 开头,去掉 /en
  5. 空路径回退为 /

示例:

getGiscusTerm('/en/docs/Travel/hong-kong-travel/')
// => '/docs/Travel/hong-kong-travel'

getGiscusTerm('/blog/post-a?preview=1#comments')
// => '/blog/post-a'

因为 giscus 使用 mapping="specific"term 就是页面和 Discussion 的绑定键。这个值一旦改动,旧评论不会丢失,但页面会关联到新的 Discussion,看起来就像评论区被重置。因此不要随意修改 term 规则。

2. 同步语言

组件通过 useDocusaurusContext() 读取当前 locale:

当前 localegiscus lang评论标题
zh-Hanszh-CN评论
enenComments

3. 同步主题

组件通过 useColorMode() 读取 Docusaurus 当前颜色模式:

Docusaurus 主题giscus 主题
lightlight
darkdark

切换站点明暗主题时,React 会重新渲染 giscus 组件并同步主题。

4. 只在布局层挂载

评论组件没有写进文章内容文件,而是写进主题布局:

// src/theme/BlogPostPage/index.js
<BlogPostItem>{children}</BlogPostItem>
<GiscusComments permalink={metadata.permalink} />
// src/theme/DocItem/Layout/index.js
<DocItemContent>{children}</DocItemContent>
<GiscusComments permalink={metadata.permalink} />
// src/theme/MDXPage/index.js
{isAboutPage && <GiscusComments permalink={metadata.permalink} />}

博客布局文件只用于博客详情页,因此博客列表页不会出现评论。文档布局中只有 isTravel 分支渲染评论,因此 Travel 之外的文档页不会出现评论。content-pages 布局中只有 getGiscusTerm(metadata.permalink) === '/about' 时渲染评论,因此 About 之外的自定义 Markdown / MDX 页面不会出现评论。

新增内容时的规则

新增博客

只要在 blog/ 新增中文博客,评论会自动出现。

如果有英文版,应放在:

i18n/en/docusaurus-plugin-content-blog/{same-file-name}

文件名和 slug 保持一致时,中英文会共用同一条 Discussion。

新增 Travel 文档

中文文件放在:

docs/Travel/{slug}.mdx

英文文件放在:

i18n/en/docusaurus-plugin-content-docs/current/Travel/{slug}.mdx

文件名和 slug 保持一致时,中英文会共用同一条 Discussion。

新增其他文档

其他文档默认不会显示评论。如果以后要给新的文档分类开启评论,应优先扩展判断函数或在 DocItem/Layout 中新增清晰的分类判断,不要在每篇文档里手动插入组件。

新增自定义页面

自定义 Markdown / MDX 页面默认不会显示评论。当前只有 About 页面通过 src/theme/MDXPage/index.js 的路径判断开启评论。如果以后要给新的自定义页面开启评论,应在 MDXPage 中新增清晰的路径判断,不要在页面内容文件里手动插入组件。

维护注意事项

不要随意改 term 规则

term 是页面和 Discussion 的主键。下面这些改动都会导致新旧评论分裂:

  • 从去掉 /en 改成保留 /en
  • 从 pathname 改成 title。
  • 从去尾斜杠改成保留尾斜杠。
  • 改文章 slug 或 permalink。

如果必须改 slug,旧 Discussion 仍在 docs-comments 仓库里,但新页面会创建新的 Discussion。需要人工在 GitHub Discussions 中迁移、合并或保留旧讨论链接。

不要把评论组件写进 MDX

当前设计是布局自动挂载。About 页面也是通过 MDXPage 布局挂载评论,而不是在 About 内容文件中引入组件。手动写进 MDX 会带来重复评论区、双语不一致和维护困难。

不限制来源域名的影响

当前没有 giscus.json,所以其他网站理论上也可以嵌入同一个 giscus 配置。实际评论仍需要 GitHub 登录,并且内容可以在 NeverGpDzy/docs-comments 的 Discussions 中删除、锁定或管理。

如果未来要限制来源,可以在评论仓库新增 giscus.json,但这会改变当前约定,需要同步更新本文档。

repoId 和 categoryId 变更

如果重建评论仓库、迁移仓库或更换 Discussion 分类,需要重新到 giscus 配置页生成 repoIdcategoryId,然后更新 src/components/GiscusComments/index.js

测试清单

每次修改评论组件或挂载逻辑后,至少运行:

npm run build
npm run build:en

重点检查页面:

页面预期
/blog/2026/05/02/hamasushi-big-conveyor-belt-sushi-meal显示评论
/en/blog/2026/05/02/hamasushi-big-conveyor-belt-sushi-meal显示同一评论
/docs/Travel/hong-kong-travel显示评论
/en/docs/Travel/hong-kong-travel显示同一评论
/about显示评论
/en/about显示同一评论
/blog不显示评论
/en/blog不显示评论
任意非 Travel 文档页不显示评论
任意非 About 自定义页面不显示评论

部署后再做一次真实评论测试:

  1. 在中文博客页发布一条测试评论。
  2. 切到对应英文博客页,确认能看到同一条评论。
  3. 在中文 Travel 页发布一条测试评论。
  4. 切到对应英文 Travel 页,确认能看到同一条评论。
  5. /about 发布一条测试评论。
  6. 切到 /en/about,确认能看到同一条评论。
  7. NeverGpDzy/docs-commentsAnnouncements 分类确认 Discussion 被创建。

故障排查

评论区标题出现,但 giscus 不加载

可能原因:

  • giscus App 没有授权到 NeverGpDzy/docs-comments
  • 评论仓库不是 public。
  • Discussions 没有启用。
  • repoIdcategoryId 写错。
  • 浏览器网络环境无法访问 GitHub 或 giscus。

中英文评论没有共用

检查:

  • 中文和英文页面的 slug 是否一致。
  • 英文路径是否是标准 /en/...
  • getGiscusTerm() 是否仍然去掉 /en
  • 是否有人手动改了某篇文章的 slug frontmatter。

非 Travel 文档页出现评论

检查 src/theme/DocItem/Layout/index.js,确认 <GiscusComments /> 仍然只在 isTravel 分支中渲染。

博客列表页出现评论

检查是否新增了 BlogPostItem/Footer 或其他列表页级别 wrapper。当前实现只应该改 BlogPostPage

About 页面不显示评论

检查 src/theme/MDXPage/index.js,确认 isAboutPage 仍然使用 getGiscusTerm(metadata.permalink) === '/about' 判断,并且渲染 <GiscusComments permalink={metadata.permalink} />

设计取舍

选择 giscus 的原因:

  • 对静态站友好,不需要后端。
  • 评论存放在 GitHub Discussions,数据可见、可管理。
  • 技术博客和知识库读者通常有 GitHub 账号。
  • 和 Docusaurus 的 React 布局集成成本低。

主要限制:

  • 访客需要 GitHub 账号才能评论。
  • 评论依赖 GitHub 和 giscus 的可用性。
  • 不限制来源域名时,嵌入权限更开放。

当前实现优先保证维护简单、双语一致和页面范围可控。