使用 giscus 为你的 Astro 博客添加评论功能

前言

在博客中添加评论功能,可以让读者和作者之间进行交流,增加互动性。本文将介绍如何为你的 Astro 博客添加评论功能。

有很多评论插件可以选择,比如 Disqus、Gitalk、Utterances 等。这里我们选择使用 giscus

什么是 giscus

giscus 是一个基于 GitHub Discussions 的评论插件。它的特点是简单易用,无需注册,支持多种主题,支持多语言,支持自定义配置。所有评论都存储在你的 GitHub Discussions 中,不会丢失,方便管理。

配置 giscus

首先,对你的仓库有一些前置要求:

以上 OK 了之后,在 giscus.app 创建你的配置。

输入你的仓库,然后我们选择用 <title> 做映射,它会作为 discussion 的标题。

分类选择 announcements。

启用以下特性:

  • reaction
  • 评论输入框在上方
  • 懒加载

主题暂时选择 dark,下面再讲主题的配置。

以上配置都搞好以后,会得到一段 script 代码。

html 复制代码
<script src="https://giscus.app/client.js"
        data-repo="username/repo"
        data-repo-id="R_kgDOKeudTw"
        data-category="Announcements"
        data-category-id="DIC_kwDOKeudT84Cch4W"
        data-mapping="title"
        data-strict="0"
        data-reactions-enabled="1"
        data-emit-metadata="0"
        data-input-position="top"
        data-theme="dark"
        data-lang="zh-CN"
        data-loading="lazy"
        crossorigin="anonymous"
        async>
</script>

这时候只要创建一个带有 .giscus class 选择器的容器,把生成的 script 复制进去,就会发现评论出现在你的页面上了。

主题切换配置

由于我的博客网站是可以切换黑暗/明亮主题的,所以我们这里安装了 @giscus/react

在 Astro 中,还需要安装 React 集成

执行以下命令:

sh 复制代码
npx astro add react
npm i @giscus/react

然后创建 Comment.tsx 组件:

tsx 复制代码
import * as React from 'react';
import Giscus from '@giscus/react';

const id = 'inject-comments';

const Comments = () => {
  const [mounted, setMounted] = React.useState(false);

  React.useEffect(() => {
    setMounted(true);
  }, []);

  return (
    <div id={id} className="w-full">
      {mounted ? (
        <Giscus
          id={id}
          repo="username/repo"
          repoId="R_kgDOKeudTw"
          category="Announcements"
          categoryId="DIC_kwDOKeudT84Cch4W"
          mapping="title"
          reactionsEnabled="1"
          emitMetadata="0"
          inputPosition="top"
          lang="zh-CN"
          loading="lazy"
          theme="dark"
        />
      ) : null}
    </div>
  );
};

export default Comments;

配置下主题的切换:

tsx 复制代码
import * as React from 'react'
import Giscus from '@giscus/react'

const id = 'inject-comments'

// 获取 localStorage 中 theme 的值
function getSavedTheme() {
  return window.localStorage.getItem('theme')
}

// 获取系统主题
function getSystemTheme() {
  return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
}

const Comments = () => {
  const [mounted, setMounted] = React.useState(false)
  const [theme, setTheme] = React.useState('light')

  React.useEffect(() => {
    const theme = getSavedTheme() || getSystemTheme()
    setTheme(theme)
    // 监听主题变化
    const observer = new MutationObserver(() => {
      setTheme(getSavedTheme())
    })
    observer.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ['data-theme'],
    })

    // 取消监听
    return () => {
      observer.disconnect()
    }
  }, [])

  React.useEffect(() => {
    setMounted(true)
  }, [])

  return (
    <div id={id} className="w-full">
      {mounted ? (
        <Giscus
          id={id}
          repo="username/repo"
          repoId="R_kgDOKeudTw"
          category="Announcements"
          categoryId="DIC_kwDOKeudT84Cch4W"
          mapping="title"
          reactionsEnabled="1"
          emitMetadata="0"
          inputPosition="top"
          lang="zh-CN"
          loading="lazy"
          theme={theme}
        />
      ) : null}
    </div>
  )
}

export default Comments

以上代码,我们初始化时,获取了 localStorage 和 系统的主题,来初始化评论主题。 然后通过 MutationObserver 来监听 document.documentElement 上的 data-theme 的值,来进行主题切换。

在 Astro 中使用评论组件

astro 复制代码
---
import Comments from "@components/Comment";
---
<!-- 使用 client:only 指令 -->
<Comments client:only="react" />

看看效果

打开 GitHub 仓库,发现 Discussions 新建了一条这篇文章的评论 discussion。

总结

整体功能完成了,我们使用了 giscus 做评论,使用了 MutationObserver 来监听主题变化,使用了 Astro 的客户端指令。同时 giscus 也不限于 Astro,也可以用在其他任何框架。快用起来吧。私聊我进新生代程序员群交流前后端开发和 AI技术。

相关推荐
啥咕啦呛13 小时前
3个月前端转全栈计划
前端
BradyC13 小时前
laya编译内存溢出问题
前端
木斯佳13 小时前
前端八股文面经大全:阿里云AI应用开发一面(2026-03-20)·面经深度解析
前端·人工智能·阿里云·ai·智能体·流式打印
绝世唐门三哥13 小时前
React--- 状态更新:何时需要拷贝,何时不需要?
javascript·react.js·ecmascript
我叫黑大帅13 小时前
JS中的两大定时器
前端·javascript·面试
掘金安东尼13 小时前
⏰前端周刊第 458 期v2026.3.24
前端·javascript·面试
前端付豪14 小时前
实现必要的流式输出(Streaming)
前端·后端·agent
张元清14 小时前
useMediaQuery:React 响应式设计完全指南
前端·javascript·面试
小金鱼Y14 小时前
一文吃透 JavaScript 防抖:从原理到实战,让你的页面不再 “手抖”
前端·javascript·面试
Z兽兽14 小时前
React 18 开发环境下useEffect 会执行两次,原因分析及解决方案
前端·react.js·前端框架