跳转至

Giscus 使用教程:为 MkDocs Material 接入 GitHub Discussions 评论

Giscus 是一个基于 GitHub Discussions 的开源评论系统。它不需要单独购买数据库或部署评论后端,评论、回复和表情反应都会保存在指定 GitHub 仓库的 Discussions 中。

它比较适合技术博客和文档站,但也有一个限制:访客需要登录 GitHub,并授权 Giscus 后才能发表评论。

本文以 MkDocs Material 为例,介绍如何接入 Giscus,并重点说明如何设置评论列表的默认排序。

一、Giscus 的工作方式

页面加载 Giscus 后,它会根据当前页面的信息查找对应的 Discussion。例如,使用 pathname 映射时:

/tools/mkdocs/giscus/
GitHub Discussion:/tools/mkdocs/giscus/

如果找不到对应的 Discussion,第一次有人发表评论或添加反应时,Giscus Bot 会自动创建一个。

因此,Giscus 主要涉及两部分:

  1. GitHub 仓库:保存 Discussions 和评论配置。
  2. 网站模板:加载 Giscus 的 client.js,并告诉它使用哪个仓库和分类。

二、准备 GitHub 仓库

可以直接使用网站源码仓库,也可以单独创建一个只保存评论的仓库。无论选择哪种方式,都需要满足以下条件:

  1. 仓库必须是公开仓库,否则普通访客无法读取 Discussion。
  2. 在仓库的 SettingsGeneralFeatures 中启用 Discussions
  3. 为该仓库安装 Giscus GitHub App

建议再进入 Discussions 页面检查分类。博客评论通常可以使用 Announcements 分类,因为这种分类能限制普通用户随意创建新 Discussion,而 Giscus 仍然可以按需创建。

三、生成 Giscus 配置

打开 Giscus 配置页面,依次完成以下设置:

  1. 输入 用户名/仓库名,等待页面验证仓库是否满足条件。
  2. 选择“页面与 Discussion 的映射关系”。
  3. 选择 Discussion 分类。
  4. 设置反应、评论框位置、主题、语言和懒加载等选项。
  5. 复制页面自动生成的 <script> 代码。

映射方式怎么选

常用映射方式如下:

映射方式 配置值 特点
页面路径 pathname 不受页面标题修改影响,文档站通常优先选择
完整地址 url 域名或 URL 结构变化后可能无法匹配旧评论
页面标题 title 地址变化时仍可能匹配,但重名或改标题时要注意
Open Graph 标题 og:title 适合已经规范配置 Open Graph 的站点
指定字符串 specific 多个页面会共用同一个 Discussion
Discussion 编号 number 精确绑定一个 Discussion,但不会自动创建

本站使用的是:

data-mapping="pathname"

使用 pathname 后,如果以后修改页面路径,Giscus 会把它当成一个新页面。迁移文档时要同步修改原 Discussion 的标题,或者保留旧 URL 的重定向策略。

四、在 MkDocs Material 中加载 Giscus

1. 启用主题覆盖目录

mkdocs.yml 中配置 custom_dir

theme:
  name: material
  custom_dir: overrides

2. 创建评论模板

创建文件:

overrides/partials/comments.html

基础写法如下。仓库 ID 和分类 ID 不要照抄示例,应以 Giscus 配置页面生成的代码为准。

{% if page.meta.comments %}
  <h2 id="__comments">{{ lang.t("meta.comments") }}</h2>

  <script
    src="https://giscus.app/client.js"
    data-repo="用户名/仓库名"
    data-repo-id="仓库ID"
    data-category="Announcements"
    data-category-id="分类ID"
    data-mapping="pathname"
    data-strict="0"
    data-reactions-enabled="1"
    data-emit-metadata="0"
    data-input-position="top"
    data-theme="preferred_color_scheme"
    data-lang="zh-CN"
    data-loading="lazy"
    crossorigin="anonymous"
    async
  ></script>
{% endif %}

外层的 {% if page.meta.comments %} 表示只有文章主动开启评论时,才加载 Giscus。

3. 为文章开启评论

在需要显示评论的 Markdown 文件顶部加入:

---
comments: true
---

没有这项配置的页面不会加载评论区。

五、让评论主题跟随网站明暗模式

data-theme="preferred_color_scheme" 会参考系统配色,但当读者在网站内手动切换主题时,Giscus iframe 不一定同步变化。

可以在 comments.html 的 Giscus <script> 后加入主题同步脚本:

<script>
  var giscus = document.querySelector("script[src*=giscus]");
  var palette = __md_get("__palette");

  if (palette && typeof palette.color === "object") {
    var theme = palette.color.scheme === "slate"
      ? "transparent_dark"
      : "light";

    giscus.setAttribute("data-theme", theme);
  }

  document.addEventListener("DOMContentLoaded", function () {
    var ref = document.querySelector("[data-md-component=palette]");
    if (!ref) return;

    ref.addEventListener("change", function () {
      var palette = __md_get("__palette");
      if (!palette || typeof palette.color !== "object") return;

      var theme = palette.color.scheme === "slate"
        ? "transparent_dark"
        : "light";
      var frame = document.querySelector(".giscus-frame");

      if (frame && frame.contentWindow) {
        frame.contentWindow.postMessage(
          { giscus: { setConfig: { theme: theme } } },
          "https://giscus.app"
        );
      }
    });
  });
</script>

这里使用 postMessage 通知已经加载完成的 Giscus iframe 切换主题,不需要重新加载评论。

六、如何修改评论列表的默认排序

这是最容易配置错的地方。

评论默认排序不能在 overrides/partials/comments.html<script> 中设置,也不存在官方支持的 data-orderdata-comment-order 属性。

Giscus 要求在保存 Discussions 的仓库根目录创建 giscus.json。例如,本站 comments.html 中配置的是:

data-repo="xiaodongxier/wiki_wangyongjie_com"

因此,应在 xiaodongxier/wiki_wangyongjie_com 仓库的默认分支根目录创建:

giscus.json

如果希望最新发表的评论排在前面,内容为:

{
  "defaultCommentOrder": "newest"
}

如果希望最早发表的评论排在前面,则使用:

{
  "defaultCommentOrder": "oldest"
}

oldest 是 Giscus 的默认值。defaultCommentOrder 目前只支持:

  • oldest:从旧到新。
  • newest:从新到旧。

如果仓库中已经有 giscus.json,不要覆盖原有配置,只需合并字段。例如:

{
  "origins": ["https://wiki.wangyongjie.com"],
  "defaultCommentOrder": "newest"
}

注意以下几点:

  1. giscus.json 必须放在 data-repo 指向的仓库,而不一定是当前网站源码仓库。
  2. 文件必须是合法 JSON,不能写注释,也不能在最后一个字段后保留逗号。
  3. 修改并提交到仓库默认分支后,刷新评论页面即可检查效果。
  4. 该配置只决定初始排序;读者仍可在评论区手动切换排序方式。

所以,针对本站的 overrides/partials/comments.html,不需要增加排序参数。真正要改的是评论仓库中的 giscus.json

本项目应该把 giscus.json 放在哪里

本站源码仓库和评论仓库是分开的:

  • 源码仓库:xiaodongxier/wangyongjie_com_admin
  • 构建及评论仓库:xiaodongxier/wiki_wangyongjie_com

当前 GitHub Actions 会执行 mkdocs build,然后把 site/ 中的文件复制到 wiki_wangyongjie_com 仓库根目录。因此,在本项目中应创建:

docs/giscus.json

构建和发布后的路径变化如下:

docs/giscus.json
        ↓ mkdocs build
site/giscus.json
        ↓ GitHub Actions 发布
wiki_wangyongjie_com/giscus.json

不要把它放在当前源码仓库根目录的 giscus.json,因为该文件不会进入 MkDocs 的 site/ 构建产物,也就不会被现有发布脚本复制到评论仓库。

七、常用参数说明

参数 作用 常用值
data-repo 保存 Discussions 的仓库 用户名/仓库名
data-repo-id GitHub 仓库的节点 ID 由配置页面生成
data-category 新 Discussion 所在分类 AnnouncementsGeneral
data-category-id Discussion 分类的节点 ID 由配置页面生成
data-mapping 页面和 Discussion 的映射方式 pathname
data-strict 是否启用严格标题匹配 01
data-reactions-enabled 是否显示主帖反应 01
data-emit-metadata 是否向父页面发送 Discussion 元数据 01
data-input-position 评论输入框的位置 topbottom
data-theme Giscus 主题 lighttransparent_dark
data-lang 界面语言 zh-CN
data-loading 是否懒加载 iframe lazy

data-repo-iddata-category-id 是公开标识,不是密码或访问令牌,可以正常提交到代码仓库。

八、常见问题

评论区没有显示

依次检查:

  1. 当前 Markdown 文件是否设置了 comments: true
  2. mkdocs.yml 是否正确配置了 theme.custom_dir
  3. comments.html 的路径是否为 overrides/partials/comments.html
  4. 仓库是否公开,并已启用 Discussions。
  5. Giscus App 是否已安装到 data-repo 指向的仓库。
  6. data-repo-iddata-category-id 是否来自当前仓库,而不是旧仓库。

页面出现了错误的评论

这通常和映射方式有关。使用标题映射时,相似标题可能被 GitHub 的模糊搜索匹配到一起。新站可以考虑开启严格匹配:

data-strict="1"

旧站开启前要先阅读 Giscus 的严格匹配迁移说明,避免现有 Discussion 无法匹配。

修改页面路径后旧评论不见了

使用 pathname 映射时,路径就是匹配依据。可以将 GitHub 中原 Discussion 的标题修改为新路径,或者在迁移前选择更稳定的映射策略。

参考资料

  1. Giscus 中文配置页面
  2. Giscus 高级用法:giscus.json 与默认排序
  3. Material for MkDocs:添加评论系统

评论