Skip to content
Go back

如何将 Giscus 评论集成到 AstroPaper 中

Updated:
Edit page

GitHub Pages 等平台上托管轻量级静态博客有很多优势,但也失去了一些交互性。幸运的是,Giscus 的存在提供了一种在静态网站上嵌入用户评论的方法。

目录

Giscus 如何工作

Giscus 使用 GitHub API 读取和存储 GitHub 用户在与存储库关联的 Discussions 中发表的评论。

在您的网站上嵌入 Giscus 客户端脚本包,使用正确的存储库 URL 对其进行配置,用户就可以查看和撰写评论(登录 GitHub 后)。

该方法是无服务器的,因为评论存储在 GitHub 上并在客户端动态加载,因此非常适合像 AstroPaper 这样的静态博客。

设置 Giscus

Giscus 可以在 giscus.app 上轻松设置,但我仍然会简要概述这个过程。

前提条件

Giscus 工作的前提条件是

如果由于任何原因无法满足这些条件中的任何一个,不幸的是,Giscus 无法集成。

配置 Giscus

接下来,需要配置 Giscus。在大多数情况下,预选的默认值是合适的,只有在您有特定原因并知道自己在做什么时才应该修改它们。不要太担心做出错误的选择;您以后随时可以调整配置。

但是您需要

配置设置后,Giscus 会为您提供一个生成的 <script> 标签,您将在接下来的步骤中需要它。

简单脚本标签

您现在应该有一个如下所示的脚本标签:

<script
  src="https://giscus.app/client.js"
  data-repo="[ENTER REPO HERE]"
  data-repo-id="[ENTER REPO ID HERE]"
  data-category="[ENTER CATEGORY NAME HERE]"
  data-category-id="[ENTER CATEGORY ID HERE]"
  data-mapping="pathname"
  data-strict="0"
  data-reactions-enabled="1"
  data-emit-metadata="0"
  data-input-position="bottom"
  data-theme="preferred_color_scheme"
  data-lang="en"
  crossorigin="anonymous"
  async
></script>

只需将其添加到网站的源代码中。很可能,如果您使用 AstroPaper 并希望在文章上启用评论,请导航到 PostDetails.astro 并将其粘贴到您希望评论出现的所需位置,也许在 Share this post on: 按钮下方。

<Layout {...layoutProps}>
  <main>
    <ShareLinks />

    <script
      src="https://giscus.app/client.js"
      data-repo="[ENTER REPO HERE]"
      data-repo-id="[ENTER REPO ID HERE]"
      data-category="[ENTER CATEGORY NAME HERE]"
      data-category-id="[ENTER CATEGORY ID HERE]"></script>
  </main>
  <Footer />
</Layout>src/layouts/PostDetails.astro

完成了!您已成功在 AstroPaper 中集成了评论!

带有浅色/深色主题的 React 组件

布局中嵌入的脚本标签是相当静态的,Giscus 配置(包括 theme)被硬编码到布局中。鉴于 AstroPaper 具有浅色/深色主题切换功能,如果评论能够与网站的其余部分一起在浅色和深色主题之间无缝切换就好了。为了实现这一点,需要一种更复杂的嵌入 Giscus 的方法。

首先,我们将安装 GiscusReact 组件

npm i @giscus/react && npx astro add react

然后我们在 src/components 中创建一个新的 Comments.tsx React 组件:

import Giscus, { type Theme } from "@giscus/react";
import { GISCUS } from "@/constants";
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/components/Comments.tsx

这个 React 组件不仅包装了原生 Giscus 组件,还引入了额外的 props,即 lightThemedarkTheme。利用两个事件监听器,Giscus 评论将与网站的主题保持一致,每当网站或浏览器主题发生变化时,在深色和浅色主题之间动态切换。

我们还需要定义 GISCUS 配置,最佳位置是在 constants.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",
};src/constants.ts

请注意,在此处指定 theme 将覆盖 lightThemedarkTheme props,导致静态主题设置,类似于之前使用 <script> 标签嵌入 Giscus 的方法。

要完成这个过程,请将新的 Comments 组件添加到 PostDetails.astro(替换上一步中的 script 标签)。

import Comments from "@/components/Comments";

<ShareLinks />

<Comments client:only="react" />

<hr class="my-6 border-dashed" />

<Footer />src/layouts/PostDetails.astro

就是这样!


Edit page
Share this post on:

Previous Post
AstroPaper 博客文章中的动态 OG 图片生成
Next Post
AstroPaper 5.0