393 字
1 分钟
Mizuki实现Giscus评论区
2025-09-13
2025-12-05
统计加载中...

准备工作#

  1. 创建专属仓库
    • 登录你的GitHub账户,新建一个 公开(public 仓库,这个仓库用于存储评论数据。
    • 进入仓库的 Settings → General 页面,向下滚动找到 Features 区域,勾选 Discussions 功能并保存。
  2. 生成配置代码
    • 访问 giscus.app,根据页面引导完成配置向导。
    • 填写你的仓库信息,选择合适的话题分类和显示偏好。
    • 配置完成后,页面会生成一段类似下面的<script>代码块,请完整复制它:
<script src="https://giscus.app/client.js"
data-repo="你的用户名/你的仓库名"
data-repo-id="你的仓库ID"
data-category="Announcements"
data-category-id="你的分类ID"
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>

配置 Mizuki 主题#

1. 修改评论配置文件#

找到项目中的 src/config.ts 文件,定位到评论配置部分。我们需要将原有的Twikoo配置替换为Giscus配置:
原内容:

export const commentConfig: CommentConfig = {
enable: false, // 启用评论功能。当设置为 false 时,评论组件将不会显示在文章区域。
twikoo: {
envId: "https://twikoo.vercel.app",
lang: "en", // 设置 Twikoo 评论系统语言为英文
},
};

修改为:

export const commentConfig: CommentConfig = {
enable: true, // 启用评论功能。当设置为 false 时,评论组件将不会显示在文章区域。
giscus: {
enable: true,
repo: "你的用户名/你的仓库名",
repoId: "你的仓库ID",
category: "Announcements",
categoryId: "你的分类ID",
mapping: "pathname",
strict: "0",
reactionsEnabled: "1",
emitMetadata: "0",
inputPosition: "top",
theme: "preferred_color_scheme",
lang: "zh-CN",
},
};

2. 添加 Giscus 组件#

在 src/components/comment/ 目录下,新建一个名为 Giscus.astro 的文件。你可以删除原有的 Twikoo.astro 文件,然后将以下代码完整复制到新文件中:

---
import { commentConfig } from "@/config";
interface Props {
path: string;
}
const giscusConfig = commentConfig.giscus;
---
<div class="giscus-container"></div>
<script is:inline define:vars={{ giscusConfig }}>
(() => {
// 1. 获取当前主题
const getTheme = () => document.documentElement.classList.contains('dark') ? 'dark' : 'light';
// 2. 核心加载函数
const loadGiscus = () => {
const root = document.querySelector('.giscus-container');
// 如果没有容器,或者容器内已经有 iframe 了,直接返回
if (!root || root.querySelector('iframe.giscus-frame')) return;
const s = document.createElement('script');
s.src = 'https://giscus.app/client.js';
s.async = true;
// 展开配置
Object.entries({
'data-repo': giscusConfig.repo,
'data-repo-id': giscusConfig.repoId,
'data-category': giscusConfig.category,
'data-category-id': giscusConfig.categoryId,
'data-mapping': giscusConfig.mapping || 'pathname',
'data-strict': giscusConfig.strict || '0',
'data-reactions-enabled': giscusConfig.reactionsEnabled || '1',
'data-emit-metadata': giscusConfig.emitMetadata || '0',
'data-input-position': giscusConfig.inputPosition || 'top',
'data-lang': giscusConfig.lang || 'zh-CN',
'data-loading': 'lazy',
'data-theme': getTheme() // 优化:直接在此处设置初始主题
}).forEach(([key, value]) => s.setAttribute(key, value));
root.appendChild(s);
};
// 3. 动态更新主题
const updateTheme = () => {
const iframe = document.querySelector('iframe.giscus-frame');
if (iframe?.contentWindow) {
iframe.contentWindow.postMessage({ giscus: { setConfig: { theme: getTheme() } } }, 'https://giscus.app');
}
};
// 4. 初始化
loadGiscus();
// 5. 监听主题变化
if (!window._giscusObserver) {
const observer = new MutationObserver((mutations) => {
// 过滤 class 变化,且 iframe 存在时才发消息
if (mutations.some(m => m.type === 'attributes' && m.attributeName === 'class')) {
updateTheme();
}
});
observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });
window._giscusObserver = observer;
}
// 6. Swup 页面切换支持
const handleSwup = () => loadGiscus();
if (window.swup) {
window.swup.hooks.on('content:replace', handleSwup);
} else {
document.addEventListener('swup:enable', () => {
window.swup?.hooks.on('content:replace', handleSwup);
}, { once: true });
}
})();
</script>
<style>
.giscus-container {
width: 100%;
margin-top: 1rem;
transition: color 0.15s, background-color 0.15s, border-color 0.15s;
}
.giscus-container iframe.giscus-frame {
width: 100% !important;
border-radius: var(--radius-large);
border: 1px solid var(--line-divider);
background: transparent;
transition: border-color 0.15s, background-color 0.15s;
}
.giscus-container:hover iframe.giscus-frame {
border-color: var(--primary);
}
:root:not(.dark) .giscus-container {
color-scheme: light;
}
:root.dark .giscus-container {
color-scheme: dark;
}
</style>

3. 更新评论组件入口#

接下来,编辑 src/components/comment/index.astro 文件,将原有的Twikoo引用替换为Giscus:
原内容:

import Twikoo from "./Twikoo.astro"; //文件内第4行
if (commentConfig?.enable && commentConfig?.twikoo) { //文件内第16行
commentService = "twikoo"; //文件内第17行
{commentService === 'twikoo' && <Twikoo path={path} />} //文件内第22行

修改为:

import Giscus from "./Giscus.astro";
if (commentConfig?.enable) {
if (commentConfig?.giscus) {
commentService = "giscus";
}
{commentService === 'giscus' && <Giscus path={path} />}

4. 更新类型定义#

最后,我们需要在TypeScript类型定义文件中添加Giscus配置的支持。打开 src/types/config.ts,找到评论配置相关的部分:
原内容:

twikoo?: TwikooConfig; //文件内第134行
type TwikooConfig = { //文件内第137行
envId: string; //文件内第138行
region?: string; //文件内第139行

修改为:

giscus?: GiscusConfig;
type GiscusConfig = {
enable: boolean;
repo: string;
repoId: string;
category: string;
categoryId: string;
mapping?: string;
strict?: string;
reactionsEnabled?: string;
emitMetadata?: string;
inputPosition?: string;
theme?: string;

完成修改#

完成以上所有步骤后,即可将原有的 Twikoo 替换为 Giscus

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

Mizuki实现Giscus评论区
https://blog.yuk1.uk/posts/mizuki-giscus/
作者
SuzuhaYuki
发布于
2025-09-13
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

封面
Sample Song
Sample Artist
封面
Sample Song
Sample Artist
0:00 / 0:00