Skip to content

如何將 Giscus 評論整合到 AstroPaper

Updated: at 12:07 PM

在像 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 並希望在帖子上啟用評論,請導航到 src/layouts/PostDetails.astro,並將其粘貼到您希望評論出現的位置,可能在 Share this post on: 按鈕下方。

      <ShareLinks />
    </div>

+    <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>

完成了!您已成功在 AstroPaper 中集成了評論!

帶有亮/暗主題的 React 組件

嵌入佈局中的腳本標籤非常靜態,Giscus 配置(包括 theme)硬編碼到佈局中。鑑於 AstroPaper 具有亮/暗主題切換功能,讓評論隨著網站的其餘部分無縫過渡到亮和暗主題會更好。為了實現這一點,需要更複雜的方法來嵌入 Giscus

首先,我們將安裝 GiscusReact 組件

npm i @giscus/react

然後我們在 src/components 中創建一個新的 Comments.tsx React 組件:

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>
  );
}

這個 React 組件不僅包裝了原生 Giscus 組件,還引入了額外的 props,即 lightThemedarkTheme。利用兩個事件監聽器,Giscus 評論將與網站的主題保持一致,當網站或瀏覽器主題更改時,動態切換亮和暗主題。

我們還需要定義 GISCUS 配置,最佳位置是在 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",
};

請注意,在此處指定 theme 將覆蓋 lightThemedarkTheme props,導致靜態主題設置,類似於之前嵌入 Giscus<script> 標籤的方法。

要完成此過程,將新 Comments 組件添加到 src/layouts/PostDetails.astro(替換上一步中的 script 標籤)。

+ import Comments from "@components/Comments";

      <ShareLinks />
    </div>

+    <Comments client:only="react" />

  </main>
  <Footer />
</Layout>

就是這樣!


Previous Post
如何配置 AstroPaper 主題
Next Post
在 AstroPaper 部落格文章中添加 LaTeX 方程式