Giscus Comment
Add dependencies
- npm
- Yarn
- pnpm
npm install --save @giscus/react
yarn add @giscus/react
pnpm add @giscus/react
Create comment compose
import React from 'react'
import { useThemeConfig, useColorMode } from '@docusaurus/theme-common'
import Giscus, { GiscusProps } from '@giscus/react'
import { useLocation } from '@docusaurus/router';
const defaultConfig: Partial<GiscusProps> = {
id: 'comments',
mapping: 'specific',
reactionsEnabled: '1',
emitMetadata: '0',
inputPosition: 'top',
loading: 'lazy',
// 用根据路径标题自动生成的 sha1 值,精确匹配 github discussion,避免路径重叠(比如父和子路径)时评论加载串了
strict: '1',
lang: 'zh-CN',
}
export default function Comment(): JSX.Element {
const themeConfig = useThemeConfig()
// merge default config
const giscus = { ...defaultConfig, ...themeConfig.giscus }
if (!giscus.repo || !giscus.repoId || !giscus.categoryId) {
throw new Error(
'You must provide `repo`, `repoId`, and `categoryId` to `themeConfig.giscus`.',
)
}
const path = useLocation().pathname.replace(/^\/|\/$/g, '');
const firstSlashIndex = path.indexOf('/');
var subPath: string = ""
if (firstSlashIndex !== -1) {
subPath = path.substring(firstSlashIndex + 1)
} else {
subPath = "index"
}
giscus.term = subPath
giscus.theme =
useColorMode().colorMode === 'dark' ? 'transparent_dark' : 'light'
return (
<Giscus {...giscus} />
)
}
Comment component loading method
In order to open comments configurable, you need to use Swizzling to adjust the page structure and embed the comment function into the page. Here is an explanation of how comments are loaded:
- Hide comments: Fully customize the page through
eject
to get the metadata of the page to determine whether it is necessary to hide comments. - Enable comments: make light modifications to the page through
wrap
In order to achieve the purpose of opening/hiding, it is necessary to modify the page components of docs, which are somewhat invasive, but eject is more invasive than wrap. When upgrading docusaurus, eject is more prone to compatibility problems, so this article uses the implementation of wrap to modify the page component.
Enable comments
docs enable comments
-
swizzle
DocItem
- npm
- Yarn
- pnpm
npm run swizzle @docusaurus/theme-classic DocItem/Layout -- --wrap --typescript
yarn swizzle @docusaurus/theme-classic DocItem/Layout --wrap --typescript
pnpm run swizzle @docusaurus/theme-classic DocItem/Layout --wrap --typescript
-
Modify the following automatically generated source code files
src/theme/DocItem/Layout/index.tsximport React from 'react';
import Layout from '@theme-original/DocItem/Layout';
import type LayoutType from '@theme/DocItem/Layout';
import type { WrapperProps } from '@docusaurus/types';
import Comment from '@site/src/components/Comment';
type Props = WrapperProps<typeof LayoutType>;
export default function LayoutWrapper(props: Props): JSX.Element {
return (
<>
<Layout {...props} />
<Comment />
</>
);
}
docs category enable comments
Here in the docs directory page will be automatically generated directory page, is made up of docusaurus DocCategoryGeneratedIndexPage
rendering
-
swizzle
DocGategoryGeneratedIndexPage
- npm
- Yarn
- pnpm
npm run swizzle @docusaurus/theme-classic DocCategoryGeneratedIndexPage -- --wrap --typescript
yarn swizzle @docusaurus/theme-classic DocCategoryGeneratedIndexPage --wrap --typescript
pnpm run swizzle @docusaurus/theme-classic DocCategoryGeneratedIndexPage --wrap --typescript
-
Modify the following automatically generated source code files
src/theme/DocCategoryGeneratedIndexPage/index.tsximport React from 'react';
import DocCategoryGeneratedIndexPage from '@theme-original/DocCategoryGeneratedIndexPage';
import type DocCategoryGeneratedIndexPageType from '@theme/DocCategoryGeneratedIndexPage';
import type { WrapperProps } from '@docusaurus/types';
import Comment from '@site/src/components/Comment';
type Props = WrapperProps<typeof DocCategoryGeneratedIndexPageType>;
export default function DocCategoryGeneratedIndexPageWrapper(props: Props): JSX.Element {
return (
<>
<DocCategoryGeneratedIndexPage {...props} />
<Comment />
</>
);
}
Hide comments
docs hide comments
-
swizzle
DocItem
- npm
- Yarn
- pnpm
npm run swizzle @docusaurus/theme-classic DocItem/Layout -- --eject --typescript
yarn swizzle @docusaurus/theme-classic DocItem/Layout --eject --typescript
pnpm run swizzle @docusaurus/theme-classic DocItem/Layout --eject --typescript
-
Modify the generated source code file.:
src/theme/DocItem/Layout/index.tsx
src/theme/DocItem/Layout/index.tsximport React from 'react';
import clsx from 'clsx';
import { useWindowSize } from '@docusaurus/theme-common';
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 Unlisted from '@theme/Unlisted';
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;
const {
metadata: { unlisted },
} = useDoc();
return (
<div className="row">
<div className={clsx('col', !docTOC.hidden && styles.docItemCol)}>
{unlisted && <Unlisted />}
<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>
);
} -
Page configuration, for docs page articles that need to be hidden, sign the markdown page with 'hide_comment: true' configuration
intro.md---
hide_comment: true
---
Other
- For the docs directory page: the idea is similar to the hidden docs page, get the metadata related to the directory, and judge the value of
hide_comment
to deal with whether it is hidden. - For the home page: If you need comments, fix import and use the
<Comment />
tag at the end of the article.
Config giscus
Giscus comment data is stored in the Discussions of the GitHub repository, so the Discussions feature is enabled in the GitHub repository Settings
-
Open
Discussions
feature -
Install authoriz
Giscus
- Open site:https://github.com/apps/giscus
- Based on my own needs, I only authorize designated warehouses here
-
Config warehouse and
Settings
-
Config 'docusaurus. config. ts' based on the configuration parameters obtained from the previous step's
<script>
content on the configuration pagedocusaurus.config.tsthemeConfig:
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
({
// giscus 评论功能
giscus: {
repo: '***************',
repoId: '************',
category: 'General',
categoryId: '********************',
},
})
After the configuration is completed, restart the project and refresh the page to see the comment area at the bottom of the article