Skip to main content

Add Disqus Comments to Docusaurus Blog Posts

· 6 min read

TL;DR Recently I have switched from Jekyll to Docusaurus for my personal website. And immediately noticed the issue with letting the visitors place comments to blog posts. It seems that the comments work out of the box only for Facebook comments and then only if one has a registered FB business site (according to this PR). Searching on adding e.g. Disqus blog comments in Docusaurus brought back more questions than answers. (see some references at the end of this post)

The closest I could get to the solution was How to add forum to Docusaurus using Utterances comments via GitHub issues. I got the gist but the vendor binding was too big to my taste.

So, I have made my own go on this issue and finally succeeded in adding the Disqus blog comments to my Docusaurus blog. In this blog post you can see them in action and also read how I did it. I hope it might help some of you to do the same on yours.

UPDATED July 12, 2022

The code examples are compatible with Docusaurus 2.0.0-beta.16 and higher

Let's Go

Prerequisites

You will need the following things in place to have ready to get the job done:

  1. your project must be running Docusaurus v2 with at least one blog post;
  2. you have installed your project using theme-classic
  3. a terminal session open in the root of your project;
  4. an account with Disqus with your registered Docusaurus web-app.

Install disqus-react:

yarn add disqus-react
# or
npm add disqus-react

If you need some guidance on Disqus weblog registration, see my Register Your Weblog with Disqus section below.


Prepare the Frontmatter

Run your Docusaurus project locally running either yarn start or npm run start in your terminal. Browse to http://localhost:3000/blog and make sure you see at least one blog post. Choose one of them to work with.

Open the chosen blog post file in your editor of choice and add the following two lines at the end of the frontmatter:

---
slug: /your-blog-post-slug
...
draft: true
comments: true # for Disqus
---

It is a good idea to keep draft value as true until you know for sure everything works fine. What it does is that it lets you see your post while running Docusaurus on localhost. But if you publish your branch to the web, this particular blog post won't be published and visible. When you are ready, you can set it to false or remove completely from the frontmatter.

The second comments property lets you decide for each blog post if you want your visitors leave comments. Set it to false and there will be no Disqus comments section underneath your blog post. Without this property or with it explicitly set to true the comments section will be present by default.

Swizzle the BlogPostItem component

Swizzling a Docusaurus component means either adding a wrapper for or including the source code of a core component into your project. This allows us to customize the component's functionality. The application will then use the swizzled and customized version of the component instead of the standard one. In our case, we will be using swizzling to add the Disqus comments on our blog post pages.

Following the tip about adding comments on the Swizzling page, let us wrap the BlogPostItem component. Run the following command and accept the warning about the risks:

yarn swizzle @docusaurus/theme-classic BlogPostItem -- --wrap
# or
npm run swizzle @docusaurus/theme-classic BlogPostItem -- --wrap

If your project uses TypeScript, add an extra --typescript flag at the end of the command line. This will copy the TypeScript version of the component and its index.d.ts types file.

DiscussionEmbed

Open the index.js file inside and let us add our custom code. I have roughly followed the instruction from the disqus-react repository but changed the code a bit to include the comments property and to add the missing details of integration with Docusaurus.

Replace the contents of the swizzled src/theme/BlogPostItem/index.js with the following code:

/src/theme/BlogPostItem/index.ts
import React from 'react'
import { DiscussionEmbed } from 'disqus-react'
import { useBlogPost } from '@docusaurus/theme-common/internal'
import BlogPostItem from '@theme-original/BlogPostItem'

export default function BlogPostItemWrapper(props) {
const { metadata } = useBlogPost()
const { frontMatter, slug, title } = metadata
const { comments = true } = frontMatter

return (
<>
<BlogPostItem {...props} />
{comments && (
<DiscussionEmbed
shortname='your-disqus-shortname'
config={{
url: slug,
identifier: slug,
title,
language: 'en_US',
}}
/>
)}
</>
)
}

If your web application has been properly registered with Disqus, you should see the Disqus comments appear under every blog post. Once you got it working locally you may set draft: false in the frontmatter or remove the setting completely and publish your project. The comments block will be there as well.

caution

The comments you add when testing your website locally do not synchronize with the comments of the same deployed page.

DO NOT CHANGE YOUR SLUGS

Be careful with changing slugs. Your existing comments are connected to it. If you change the slug, you will loose them. If that happens, just restore the old slug.

CommentCount and CommentEmbed

Using the disqus-react code snippets for CommentCount and CommentEmbed it is also possible to add those to your Docusaurus project in a similar manner.


Final Observations

While swizzling is handy, it is still some sort of a patch or workaround. So, if Docusaurus in some future release changes the code or signature of the component, you will probably need to swizzle their new versions. Meaning that you will also need to reapply the patch described here.

This has already happened in Docusaurus 2.0.0-beta.16. In the initial version of this article in January 2021, I was ejecting the BlogPostPage component and changing the core code inside. At that time, there was no wrapping option. Then in January 2022, Sébastien Lorber, one of the maintainers of Docusaurus, posted this comment:

Docusaurus maintainer here, thanks for the blog post. Note that in 2022 and for the v2 release we'll improve and make this easier to add comments.

Basically, instead of copying internal implementation details, you'll just "wrap" an existing component (like BlogContent) to add your comment system just under https://docusaurus.io/docs/...

We are working on a new "docusaurus swizzle --wrap" CLI to encourage this pattern, and thinking about good component granularity so that this pattern can be useful to solve many use-cases

Thanks to Sébastien, I have used this new wrapping option and updated the blog post accordingly.