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

相关推荐
旧曲重听129 分钟前
最快实现的前端灰度方案
前端·程序人生·状态模式
默默coding的程序猿38 分钟前
3.前端和后端参数不一致,后端接不到数据的解决方案
java·前端·spring·ssm·springboot·idea·springcloud
夏梦春蝉43 分钟前
ES6从入门到精通:常用知识点
前端·javascript·es6
归于尽1 小时前
useEffect玩转React Hooks生命周期
前端·react.js
G等你下课1 小时前
React useEffect 详解与运用
前端·react.js
我想说一句1 小时前
当饼干遇上代码:一场HTTP与Cookie的奇幻漂流 🍪🌊
前端·javascript
funnycoffee1231 小时前
Huawei 6730 Switch software upgrade example版本升级
java·前端·华为
小鱼小鱼干1 小时前
【Tauri】Tauri中Channel的使用
前端
拾光拾趣录1 小时前
CSS全面指南:从基础布局到高级技巧与实践
前端·css
南屿im1 小时前
基于 Promise 封装 Ajax 请求:从 XMLHttpRequest 到现代化异步处理
前端·javascript