输入搜索…

· client · 2 min 阅读

解决 giscus 主题切换问题

在 Astro 中使用 giscus 并解决主题切换同步问题

解决 giscus 主题切换问题

@rodrigoesant

背景

为了在博客文章下实现评论功能,我最终选择了 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>

注意事项

  1. frontmatter 变量传递给脚本 参考链接
  2. data-repo-iddata-category-id 可以在 giscus 官网 查看
分享:
返回文章列表