· client · 2 min 阅读
解决 giscus 主题切换问题
在 Astro 中使用 giscus 并解决主题切换同步问题
背景
为了在博客文章下实现评论功能,我最终选择了 giscus 方案。giscus 是一个依赖 GitHub Discussions 实现的评论系统。但它在主题切换过程中,无法实现动态主题更新,我利用了主题切换监听,在 Astro 中实现了这个功能。
实现
AstroGiscus.astro
自定义组件
---
interface Props {
category?: string;
categoryId?: string;
}
const { category, categoryId } = Astro.props;
---
<astro-giscus data-category={category} data-category-id={categoryId}>
<div class="giscus mx-auto px-6 sm:px-6 max-w-3xl pt-8 md:pt-4 pb-12 md:pb-20"></div>
</astro-giscus>
<script>
class AstroGiscus extends HTMLElement {
constructor() {
super();
this.initializeGiscus();
}
initializeGiscus() {
document.addEventListener('DOMContentLoaded', () => {
this.setupThemeToggle();
this.loadGiscusScript();
});
}
setupThemeToggle() {
const toggle = document.querySelector('label[for="theme-switcher"]');
if (toggle) {
// 监听自己的主题切换按钮点击事件
toggle.addEventListener('click', this.handleThemeToggle);
}
}
handleThemeToggle() {
const currentTheme = localStorage.getItem('theme') || 'light';
const newTheme = currentTheme === 'light' ? 'dark' : 'light';
AstroGiscus.setGiscusTheme(newTheme);
}
static setGiscusTheme(theme) {
const iframe = document.querySelector('iframe.giscus-frame');
if (!iframe) return;
iframe.contentWindow.postMessage({ giscus: { setConfig: { theme } } }, 'https://giscus.app');
}
loadGiscusScript() {
const theme = localStorage.getItem('theme') || 'light';
const category = this.dataset.category || 'Blog';
const categoryId = this.dataset.categoryId || 'DIC_kwDOK1aVGs4CgMLo';
const script = document.createElement('script');
script.src = 'https://giscus.app/client.js';
script.setAttribute('data-repo', 'dacong-wu/astro-blog');
script.setAttribute('data-repo-id', 'R_kgDOK1aVGg');
script.setAttribute('data-category', category);
script.setAttribute('data-category-id', categoryId);
script.setAttribute('data-mapping', 'pathname');
script.setAttribute('data-strict', '0');
script.setAttribute('data-reactions-enabled', '1');
script.setAttribute('data-emit-metadata', '0');
script.setAttribute('data-input-position', 'bottom');
script.setAttribute('data-theme', theme);
script.setAttribute('data-lang', 'zh-CN');
script.setAttribute('crossorigin', 'anonymous');
script.async = true;
document.head.appendChild(script);
}
}
customElements.define('astro-giscus', AstroGiscus);
</script>