Add Giscus Comments to Docusaurus 3 Blog Posts and Doc Pages
Giscus is a handy open-source web application that effortlessly integrates GitHub Discussions into external platforms. It lets you add a comment section to any static website without the hassle of setting up a separate database. Giscus stores all the data right in GitHub Discussions.
In the next sections, I will guide you through the step-by-step process of configuring and incorporating Giscus into your static Docusaurus 3 website.
Prerequisites
- GitHub account
- Docusaurus 3 website (classic theme)
Set up the Repository
To enable Giscus for your GitHub repository, follow these steps:
-
The repository must be public, otherwise visitors will not be able to view the discussion.
-
Enable the Discussions feature for your chosen repository. If your website is hosted on GitHub Pages, this can be the same repository, as long as it is public.
-
Install and configure the Giscus GitHub app, otherwise visitors will not be able to comment and react.
Integrate with Docusaurus
Create the Giscus Configuration
For a hassle-free configuration, visit the official Giscus website.
The web app features a user-friendly form that guides you through generating the configuration.
Notably, it automatically fetches essential details like repo-id and category-id, which can otherwise be difficult to determine.
Once you've input all the necessary information, a concise summary, as seen below, will be shown at the bottom of the form:
<script src="https://giscus.app/client.js"
data-repo="giscus/giscus"
data-repo-id="MDEwOlJlcG9zaXRvcnkzNTE5NTgwNTM="
data-category="General"
data-category-id="MDE4OkRpc2N1c3Npb25DYXRlZ29yeTMyNzk2NTc1"
data-mapping="pathname"
data-strict="1"
data-reactions-enabled="1"
data-emit-metadata="0"
data-input-position="top"
data-theme="preferred_color_scheme"
data-lang="en"
data-loading="lazy"
crossorigin="anonymous"
async>
</script>
Implement the Comments Component
Start by installing the @giscus/react package. Giscus offers a convenient React wrapper package that you can add using:
- npm
- Yarn
- pnpm
- Bun
npm install @giscus/react
yarn add @giscus/react
pnpm add @giscus/react
bun add @giscus/react
Next, proceed with implementing the new Comments component.
Utilize the configuration obtained in the previous section.
Note that the prop names for the Giscus React component mirror the data- attributes displayed on the Giscus website, but they are written in camelCase without the data- prefix.
A complete example implementation is presented below:
import type { ReactNode } from "react";
import Giscus from "@giscus/react";
import { useColorMode } from "@docusaurus/theme-common";
export default function Comments(): ReactNode {
const { colorMode } = useColorMode();
return (
<div>
<Giscus
id="comments"
repo="giscus/giscus"
repoId="MDEwOlJlcG9zaXRvcnkzNTE5NTgwNTM="
category="General"
categoryId="MDE4OkRpc2N1c3Npb25DYXRlZ29yeTMyNzk2NTc1"
mapping="pathname"
strict="1"
reactionsEnabled="1"
emitMetadata="0"
inputPosition="top"
theme={colorMode === "dark" ? "dark_tritanopia" : "light_tritanopia"}
lang="en"
loading="lazy"
/>
</div>
);
}
Prepare Front Matter
Front matter is used to add metadata to Markdown files.
By introducing a new comments property, you gain the ability to selectively enable or disable comments on each page and decide whether visitors can leave comments on individual blog posts.
Setting it to false ensures no Giscus comments section will appear for that page, while omitting the property follows the default you set in your wrapper component.
To update an existing blog post, simply add the following line at the end of the front matter of the blog post file:
---
slug: your-slug
...
comments: true # for Giscus
---
Exercise caution when altering slugs after a page is published, as your existing comments are tied to them when you use mapping="pathname".
Changing the slug will break the automatic mapping and result in lost comments and reactions!
Add Comments to Blog Posts
Swizzling a Docusaurus component enables you to replace a theme component with your own implementation. It involves creating a wrapper around the original theme component, which can then be enhanced, allowing customization of its functionality. This customized version of the component is then utilized by the application instead of the standard one.
In our case, we'll use swizzling to integrate Giscus comments into our blog post pages, leveraging the Comments component created earlier.
Execute the following command to swizzle the BlogPostItem component. Be sure to accept the warning about potential risks.
- npm
- Yarn
- pnpm
- Bun
npm run swizzle @docusaurus/theme-classic BlogPostItem -- --wrap --typescript
yarn swizzle @docusaurus/theme-classic BlogPostItem --wrap --typescript
pnpm run swizzle @docusaurus/theme-classic BlogPostItem --wrap --typescript
bun run swizzle @docusaurus/theme-classic BlogPostItem --wrap --typescript
Executing this command will generate a new file in the src/theme folder, which can be edited and adjusted as follows.
Pay attention to the isBlogPostPage variable, which is crucial to ensure that comments are not displayed on the blog overview page.
import type { ReactNode } from "react";
import BlogPostItem from "@theme-original/BlogPostItem";
import type BlogPostItemType from "@theme/BlogPostItem";
import type { WrapperProps } from "@docusaurus/types";
import { useBlogPost } from "@docusaurus/plugin-content-blog/client";
import Comments from "@site/src/components/Comments";
type Props = WrapperProps<typeof BlogPostItemType>;
export default function BlogPostItemWrapper(props: Props): ReactNode {
const { metadata, isBlogPostPage } = useBlogPost();
const { comments = true } = metadata.frontMatter;
return (
<>
<BlogPostItem {...props} />
{comments && isBlogPostPage && <Comments />}
</>
);
}
Add Comments to Doc Pages
Similarly, Giscus comments can also be added to doc pages.
- npm
- Yarn
- pnpm
- Bun
npm run swizzle @docusaurus/theme-classic DocItem/Footer -- --wrap --typescript
yarn swizzle @docusaurus/theme-classic DocItem/Footer --wrap --typescript
pnpm run swizzle @docusaurus/theme-classic DocItem/Footer --wrap --typescript
bun run swizzle @docusaurus/theme-classic DocItem/Footer --wrap --typescript
import type { ReactNode } from "react";
import DocItemFooter from "@theme-original/DocItem/Footer";
import type DocItemFooterType from "@theme/DocItem/Footer";
import type { WrapperProps } from "@docusaurus/types";
import { useDoc } from "@docusaurus/plugin-content-docs/client";
import Comments from "@site/src/components/Comments";
type Props = WrapperProps<typeof DocItemFooterType>;
export default function DocItemFooterWrapper(props: Props): ReactNode {
const { metadata } = useDoc();
const { comments = false } = metadata.frontMatter;
return (
<>
<DocItemFooter {...props} />
{comments && <Comments />}
</>
);
}