818 字
4 min
Giscus在astro上的实现方案

话说在前#

说不了一点,懒得水了

普通导入#

如果你不需要那些七七八八的东西就普通导入就行

准备工作#

  1. 先去找到你要存放评论的仓库,必须是public,然后开启了discussion

  2. 打开giscus官网,默认设置即可,然后复制配置文件

<script src="https://giscus.app/client.js"
data-repo="yCENzh/Fuwari-yCENzh"
data-repo-id="114514"
data-category="Announcements"
data-category-id="1919810"
data-mapping="pathname"
data-strict="0"
data-reactions-enabled="1"
data-emit-metadata="0"
data-input-position="top"
data-theme="preferred_color_scheme"
data-lang="zh-CN"
data-loading="lazy"
crossorigin="anonymous"
async>
</script>

Astro配置#

接下来对项目动刀,打开src/components/目录下创建一个.astro文件,名字随意,这里以src/components/misc/Giscus.astro为例,粘贴复制好的配置,保存退出

<script src="https://giscus.app/client.js"
data-repo="yCENzh/Fuwari-yCENzh"
data-repo-id="R_kgDOPe85cQ"
data-category="Announcements"
data-category-id="DIC_kwDOPe85cc4CuYZG"
data-mapping="pathname"
data-strict="0"
data-reactions-enabled="1"
data-emit-metadata="0"
data-input-position="top"
data-theme="preferred_color_scheme"
data-lang="zh-CN"
data-loading="lazy"
crossorigin="anonymous"
async>
</script>

在你想要放评论区的地方导入元素,以本框架Fuwari为例,元素位置放在许可证卡片下~(好像叫版权信息)~,修改动态路由src/pages/posts/[...slug].astro

[...slug].astro
import Giscus from "../../components/misc/Giscus.astro"; // 导入Giscus
...
<div>
<div>
...
{licenseConfig.enable && <License ...></License>}
<Giscus /> // Giscus
</div>
</div>
...

初入门径#

Giscus自带的preferred_color_scheme只会监听系统级的主题变化,并不会监听FuwarisetTheme函数,会导致手动切换Fuwari主题时,Giscus并不会同步更新,因此这里手动写出逻辑,并添加comments元数据来控制评论区是否显示

Giscus.astro进行修改(请手动替换成自己的配置)

Giscus.astro
---
interface Props {
repo: string;
repoId: string;
category: string;
categoryId: string;
mapping?: string;
reactionsEnabled?: boolean;
emitMetadata?: boolean;
inputPosition?: 'top' | 'bottom';
lang?: string;
}
const {
repo = "yCENzh/Fuwari-yCENzh" // 替换成你自己的
repoId = "114514" // 替换成你自己的
category = "Announcements" // 替换成你自己的
categoryId = "1919810" // 替换成你自己的
mapping = 'pathname',
reactionsEnabled = true,
emitMetadata = false,
inputPosition = 'bottom',
lang = 'zh-CN'
} = Astro.props;
---
<div id="giscus-container"></div>
<script define:vars={{ repo, repoId, category, categoryId, mapping, reactionsEnabled, emitMetadata, inputPosition, lang }}>
function loadGiscus() {
const container = document.getElementById('giscus-container');
if (!container) return;
// 获取当前主题
const isDark = document.documentElement.classList.contains('dark');
const theme = isDark ? 'dark' : 'light';
// 创建Giscus脚本
const script = document.createElement('script');
script.src = 'https://giscus.app/client.js';
script.setAttribute('data-repo', repo);
script.setAttribute('data-repo-id', repoId);
script.setAttribute('data-category', category);
script.setAttribute('data-category-id', categoryId);
script.setAttribute('data-mapping', mapping);
script.setAttribute('data-strict', '0');
script.setAttribute('data-reactions-enabled', reactionsEnabled ? '1' : '0');
script.setAttribute('data-emit-metadata', emitMetadata ? '1' : '0');
script.setAttribute('data-input-position', inputPosition);
script.setAttribute('data-theme', theme);
script.setAttribute('data-lang', lang);
script.setAttribute('data-loading', 'lazy');
script.crossOrigin = 'anonymous';
script.async = true;
container.appendChild(script);
}
// 监听主题变化
function updateGiscusTheme() {
const giscusFrame = document.querySelector('iframe[src*="giscus"]');
if (giscusFrame) {
const isDark = document.documentElement.classList.contains('dark');
const theme = isDark ? 'dark' : 'light';
giscusFrame.contentWindow.postMessage({
giscus: {
setConfig: {
theme: theme
}
}
}, 'https://giscus.app');
}
}
// 监听DOM变化来检测主题切换
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
updateGiscusTheme();
}
});
});
// 页面加载时初始化
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', loadGiscus);
} else {
loadGiscus();
}
// 开始观察主题变化
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class']
});
</script>

src/pages/posts/[...slug].astro中导入

也就是在你所需要的地方添加,例如我的在 文章页面-许可证卡片下

[...slug].astro
---
import { getCollection } from 'astro:content'
import MainGridLayout from '@layouts/MainGridLayout.astro'
import License from '@components/misc/License.astro'
import Giscus from '@components/misc/Giscus.astro' // 导入 Giscus
// ... 其他导入
---
<MainGridLayout banner={entry.data.image} title={entry.data.title}>
<div slot="main" class="flex w-full flex-col">
<div class="mb-6">
<!-- 文章内容 -->
<Content />
</div>
<div class="flex w-full flex-col gap-4">
<!-- 其他组件 -->
<!-- 版权信息 -->
{licenseConfig.enable && (
<License
title={entry.data.title}
pubDate={entry.data.published}
url={Astro.url.href}
/>
)}
<!-- 渲染评论区 -->
<Giscus />
</div>
</div>
<!-- 侧边栏等其他内容 -->
</MainGridLayout>

说在最后#

由于个人习惯性将各种杂七杂八的分开文件写,再统一导入,当然你也可以直接将Giscus.astro的内容直接写入你想要的地方,不用新建文件,个人习惯而已

The end Ciallo~

Giscus在astro上的实现方案
https://fuwari.oh1.top/posts/fuwari/giscus/
作者
yCENzh
发布于
2025-08-21