内容目录
可选方案
在 2024 年给静态博客添加评论系统的可选方案已有很多。本文选择依赖 GitHub Discussion 的方案 giscus。
giscus 的配置方法请参见官方文档 https://giscus.app/zh-CN。
实现方式
在 Astro 中,使用 giscus 的方法是:在官方获得你的 script 代码段后,插入到 src/layouts/PostDetails.astro
中的 </main>
前。
<main>
...
<script src="https://giscus.app/client.js"
data-repo="[ENTER REPO HERE]"
...
</script>
</main>
组件化
组件化是一种将页面中重复的代码片段提取出来,以组件的形式进行封装,方便代码复用的方式。
此时,我们先运行
npm i @giscus/react
然后在组件目录 src/components
创建一个 Comments.tsx
的 React 组件:
源码请见 Comments.tsx
import Giscus, { type Theme } from "@giscus/react";
import { GISCUS } from "@config";
import { useEffect, useState } from "react";
interface CommentsProps {
lightTheme?: Theme;
darkTheme?: Theme;
}
export default function Comments({
lightTheme = "light",
darkTheme = "dark",
}: CommentsProps) {
const [theme, setTheme] = useState(() => {
const currentTheme = localStorage.getItem("theme");
const browserTheme = window.matchMedia("(prefers-color-scheme: dark)")
.matches
? "dark"
: "light";
return currentTheme || browserTheme;
});
useEffect(() => {
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
const handleChange = ({ matches }: MediaQueryListEvent) => {
setTheme(matches ? "dark" : "light");
};
mediaQuery.addEventListener("change", handleChange);
return () => mediaQuery.removeEventListener("change", handleChange);
}, []);
useEffect(() => {
const themeButton = document.querySelector("#theme-btn");
const handleClick = () => {
setTheme(prevTheme => (prevTheme === "dark" ? "light" : "dark"));
};
themeButton?.addEventListener("click", handleClick);
return () => themeButton?.removeEventListener("click", handleClick);
}, []);
return (
<div className="mt-8">
<Giscus theme={theme === "light" ? lightTheme : darkTheme} {...GISCUS} />
</div>
);
}
并在 src/config.ts
加入
import type { GiscusProps } from "@giscus/react";
export const GISCUS: GiscusProps = {
repo: "[ENTER REPO HERE]",
repoId: "[ENTER REPO ID HERE]",
category: "[ENTER CATEGORY NAME HERE]",
categoryId: "[ENTER CATEGORY ID HERE]",
mapping: "pathname",
reactionsEnabled: "0",
emitMetadata: "0",
inputPosition: "bottom",
lang: "en",
loading: "lazy",
};
最后,替换刚才 </main>
前的 script 标签。
<main>
...
<Comments client:only />
</main>
至此,你已按 Astro 的方式添加了 giscue 评论系统。