Adding Disqus to Gatsby

July 10, 2018

The migration from Hugo to GatsbyJS went pretty well so far, but I didn’t have time to investigate how to embed the comment section. Today, it actually took me a while to get Disqus to load correctly within Gatsby, so I thought I’d write down my solution in case it’s useful to others.

Help, There’re No Working Disqus Components!

There’re apparently various Disqus-React components floating around - the official 'disqus-react' package, the 3 years old 'react-disqus-thread' almost every tutorial is talking about, or its younger fork 'react-disqus-comments'. Using Gatsby with Disqus is also discussed numerous times in several Gatsby issues (like #131) as well as many blog posts (by Matt Kane for example - I’m also using the blog starter kit, but for Gatsby version 2).

In theory, the only things needed for Disqus are a “short name” (for telling Disqus which site we are talking about) and some URL, title configs which can be all empty - Disqus will use window.location.href and <title> attribute to fill in the blanks.

However, nothing seemed to work. I mean, apparently, the loading indicator of Disqus was the only thing that was working. What’s wrong here?

My Mistake

After reading this comment, I finally realized that Disqus was probably being picky with its config parameters. I removed all custom configs, and it worked! Curious!

After poking around for another while, it turned out that my mistake was simply not realizing the location prop passed around in Gatsby is an object, not literally the current URL sub path string!

I settled down with the official 'disqus-react' in the end, but I figure it is the same with any other wrappers. This is what my current working setup looks like:

import Disqus from 'disqus-react'

class BlogPostTemplate extends Component {
  render() {
    const post = this.props.data.markdownRemark
    const disqusConfig = {
      url: `https://www.xiaoru.li${this.props.location.pathname}`,
      identifier: `${this.props.location.pathname}`,
      title: post.frontmatter.title,
    }

    // Below is the version that blew the comment section up...

    // const disqusConfig = {
    //   url: `https://www.xiaoru.li${this.props.location}`,
    //   identifier: this.props.location,
    //   title: post.frontmatter.title,
    // }

    return (
      <Layout>
        {/* blah blah blah */}
        <Disqus.DiscussionEmbed shortname="xiaoru-li" config={disqusConfig} />
        {/* blah blah blah */}
      </Layout>
    )
  }
}

I set the URL prefix to be the “www” version and the identifier to be the sub path of posts, which I think will make things easier if I ever have to migrate the site again.

The location prop is an object which is being passed around within Gatsby’s router. I haven’t digged into routing yet, but this object simply looks like { pathname: string; search: string; hash: string }.

Thoughts on Migrations

Since Disqus comment threads are linked to their identifiers plus the site short name, you’ll very likely lose all your comments if you change the url structure of your site (or domain name). If you were never asked by your CMS or SSG to set up Disqus with anything more than a short name (like me back in the Hugo days) you’re most likely using the defaults, that is, the not-so-trusty URLs will be used as the identifiers.

Fortunately (and unfortunately), my tiny blog only has little traffic let alone comments, so it wouldn’t be that painful if I did “disappear” from Disqus or any search results! 😆