Skip to main content

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 install @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:

/src/components/Comments/index.tsx
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
---
DO NOT CHANGE YOUR SLUGS

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 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.

/src/theme/BlogPostItem/index.tsx
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 run swizzle @docusaurus/theme-classic DocItem/Footer -- --wrap --typescript
/src/theme/DocItem/Footer/index.tsx
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 />}
</>
);
}