跳到主要内容

Giscus 评论系统

这里使用的是 Giscus,基于 Github Discussions,评论的信息可以通过 Github 邮箱发送,比较友好。

配置前提

  • 该仓库是个公开的,否则方可无法看到 Discussions(随便一个仓库就行,不一定是博客项目)
  • giscus app 已安装,否则无法评论与回应。
  • Discussions 功能已经在仓库里开启

本博客项目已经配置了评论组件,在目录下 src/component/Comment,只需在 docusaurus.config.js 配置相关信息即可。

配置 giscus

打开 giscus 官网,填写相关信息,然后就会得到一个已经配置好的 script 标签

data-repo, data-repo-id, data-categorydata-category-id 填写到 docusaurus.config.js 中即可。

一定要用自己的,如果直接复制别的那评论信息就跑到别人那去了!

<script src="https://giscus.app/client.js"
data-repo="Shake-Jarjane/Docusaurus-Blog"
data-repo-id="xxxxxxxx"
data-category="General"
data-category-id="DIC_kwDOIyryJM4CTqoJ"
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="zh-CN"
crossorigin="anonymous"
async>
</script>
docusaurus.config.js
giscus: {
repo: 'Shake-Jarjane/Docsusaurus-Blog',
repoId: 'R_kgDOIyryeJA',
category: 'General',
categoryId: 'DIC_kweDOIyryJM4CTqoJ',
mapping: 'title',
lang: 'zh-CN',
},

到这里评论服务的配置就完成了,你可以自行到自己的文章下面测试一下,发表评论之后,如果正常你会收到邮件提醒。

docs 文章界面开启评论服务

现在只有 blog 文章下面有评论功能,如果 docs 界面也要开启评论功能的话,但由于 Docusaurus 的 bug 导致切换文档时,在未刷新网页的情况下 Giscus 有时获取的仍然是上一篇文章的评论,为解决这一问题需要做一些小修改,参考以下方法:

安装所需包

yarn add @giscus/react mitt

封装评论组件

报错的话不用理,只需确认评论功能是否正常即可

配置声明周期函数

在根目录下创建文件 src/clientModules/routeModules.ts

src/clientModules/routeModules.ts
import mitt from 'mitt';
import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';

const emitter = mitt();

if (ExecutionEnvironment.canUseDOM) {
window.emitter = emitter;
}

export function onRouteDidUpdate() {
if (ExecutionEnvironment.canUseDOM) {
setTimeout(() => {
window.emitter.emit('onRouteDidUpdate');
});
}
// https://github.com/facebook/docusaurus/issues/8278
}

修改评论组件

直接复制并将原有的覆盖即可

src/components/comment/index.tsx
import {useColorMode} from '@docusaurus/theme-common';
import BrowserOnly from '@docusaurus/BrowserOnly';
import React, { forwardRef, useEffect, useState } from 'react';
import Giscus, { GiscusProps } from '@giscus/react';
import { useThemeConfig, ThemeConfig } from '@docusaurus/theme-common';

interface CustomThemeConfig extends ThemeConfig {
giscus: GiscusProps & { darkTheme: string };
}

export const Comment = forwardRef<HTMLDivElement>((_props, ref) => {
const themeConfig = useThemeConfig() as any;
const theme = useColorMode().colorMode === 'dark' ? 'dark' : 'light';
const { giscus } = useThemeConfig() as CustomThemeConfig;
const [routeDidUpdate, setRouteDidUpdate] = useState(false);

useEffect(() => {
function eventHandler(e) {
setRouteDidUpdate(true);
}

window.emitter.on('onRouteDidUpdate', eventHandler);

return () => {
window.emitter.off('onRouteDidUpdate', eventHandler);
};
}, []);

if (!routeDidUpdate) {
return null;
}

const options: GiscusProps = {
...(themeConfig.giscus as GiscusProps),
id: 'comments',
reactionsEnabled: '1',
emitMetadata: '0',
inputPosition: 'top',
theme,
};
return (
<BrowserOnly fallback={<div>Loading Comments...</div>}>
{() => <Giscus {...options} />}
</BrowserOnly>
);
});

export default Comment;

安装 swizzling 文档页面对应组件

yarn run swizzle @docusaurus/theme-classic DocItem/Layout -- --eject --typescript

这里他会报一个警告,选择 yes 就行 20230125144249

为什么会报警告呢?这是官方文档给的部分说明: 20230125144319

完成后就会在根目录下生成如下文件 20230125144343

这里需要进行一点修改,添加如下代码

点击展开
import React from 'react';
import clsx from 'clsx';
import { useWindowSize } from '@docusaurus/theme-common';
// @ts-ignore
import { useDoc } from '@docusaurus/theme-common/internal';
import DocItemPaginator from '@theme/DocItem/Paginator';
import DocVersionBanner from '@theme/DocVersionBanner';
import DocVersionBadge from '@theme/DocVersionBadge';
import DocItemFooter from '@theme/DocItem/Footer';
import DocItemTOCMobile from '@theme/DocItem/TOC/Mobile';
import DocItemTOCDesktop from '@theme/DocItem/TOC/Desktop';
import DocItemContent from '@theme/DocItem/Content';
import DocBreadcrumbs from '@theme/DocBreadcrumbs';
import type { Props } from '@theme/DocItem/Layout';

import styles from './styles.module.css';
import Comment from '../../../components/Comment';

/**
* Decide if the toc should be rendered, on mobile or desktop viewports
*/
function useDocTOC() {
const { frontMatter, toc } = useDoc();
const windowSize = useWindowSize();

const hidden = frontMatter.hide_table_of_contents;
const canRender = !hidden && toc.length > 0;

const mobile = canRender ? <DocItemTOCMobile /> : undefined;

const desktop =
canRender && (windowSize === 'desktop' || windowSize === 'ssr') ? (
<DocItemTOCDesktop />
) : undefined;

return {
hidden,
mobile,
desktop
};
}

export default function DocItemLayout({ children }: Props): JSX.Element {
const docTOC = useDocTOC();
const { frontMatter } = useDoc();
const { hide_comment: hideComment } = frontMatter;

return (
<div className="row">
<div className={clsx('col', !docTOC.hidden && styles.docItemCol)}>
<DocVersionBanner />
<div className={styles.docItemContainer}>
<article>
<DocBreadcrumbs />
<DocVersionBadge />
{docTOC.mobile}
<DocItemContent>{children}</DocItemContent>
<DocItemFooter />
</article>
<DocItemPaginator />
</div>
{!hideComment && <Comment />}
</div>
{docTOC.desktop && <div className="col col--3">{docTOC.desktop}</div>}
</div>
);
}

修改 docusaurus.config.js 文件

module.exports = {
themeConfig: {
giscus: {
repo: 'xxx',
repoId: 'xxx',
category: 'Announcements',
categoryId: 'xxx'
}
},
clientModules: [require.resolve('./src/clientModules/routeModules.ts')]
};

完成以上步骤后即可以到你文档界面查看就可以了(Swizzling 后需要重新运行 Docusaurus ,不然是无法看到效果的)。
对于某些不想开启评论功能的文章,只需在前言中加入:hide_comment: true

参考与致谢