使用 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技术。

相关推荐
AI源码21 分钟前
鲜花商城(HTML 版)
前端·html
hiahiahia12328 分钟前
Message 和对话
服务器·前端·数据库
溪语流沙1 小时前
【Web全栈进阶】Composition API与组件通信:props深入、emit、插槽
前端·css·vue.js
ZoeLandia1 小时前
TypeScript 03:泛型与工具类型
前端·typescript
code_Bo1 小时前
从策划到上线:我和 AI 一起做了个微信记账小程序
前端·ai编程·cursor
Shirley~~1 小时前
Three.js加载Gltf模型并播放动画
前端·3d
Data analyse4561 小时前
Session超时与浏览器休眠的计时校验
大数据·前端·数据库·数据分析
星始流年1 小时前
AI 时代,软件程序员未来 10—15 年的职业前景
前端·后端·ai编程
猪猪拆迁队2 小时前
跨电脑复制共享-局域网直连踩坑
前端·后端·go
静默回滚2 小时前
逐帧处理视频的内存去哪了,我从看错读数查到没排队
前端