Blog » How to integrate Disqus comments in React app

How to integrate Disqus comments in React app

2017-09 |

This content is only available in english

How to integrate Disqus comments in React app

One of the challenges that I faced while programming this, so far, very simple blog app (the one that you are using to read this post, most likely), was how to give my readers a possibility to comment on my posts. Obviously, it is one of the crucial features of this kind of app – I would like my readers to be able to tell me where am I wrong, and I would like me to be able to respond to such heretic claims. However, the whole feature seems quite a lot of work to implement from scratch. Luckily, there are plenty of ready out of the box solutions out there, one of them being Disqus.

I’m sure there are other providers of such feature, but I decided to go for this one, because it has a possibility to log in with your Google, Facebook, or Twitter account, and – more importantly – it’s super simple to integrate it with React. Once I figured it out, I decided to share this very basic setup in a form of short note.

First of all, you’ll need a Disqus account. After successful registration, you need to add your website, providing it’s name and URL address. When it’s done, you’ll see plenty of predefined content management systems to integrate with. You don’t need that. You’re keen on the code, you can do it yourself, so you scroll down to the manual integration part and copy configuration code, that you’ll paste somewhere on your website. Just remember to provide appropriate page url (root of your website) and identifier (based on variable, related to the specific page, which will be the subject of reader’s comments; in my case it’s part of given blog post’s nice URL).

var disqus_config = function () {
    this.page.url = 'https://soofka.pl';
    this.page.identifier =
        document.location.href.substr(
            document.location.href.indexOf(this.page.url) + this.page.url.length
        );
};
(function() {
    var d = document, s = d.createElement('script');
    s.src = 'https://soofka-pl.disqus.com/embed.js';
    s.setAttribute('data-timestamp', +new Date());
(d.head || d.body).appendChild(s);
})();

Once the script above is ready, you need to add it to your site. Some people are adding things like this to their application code, but I, for one, prefer keeping this and other scripts from external providers in static assets directory. All assets from there are copied by Webpack to my resulting package during build process. For details of my setup check this blog on github.

You’re halfway done. Really! The only remaining part is to place your Disqus comment box on your page of choice. For React application, you’d probably like to have separate component for comments. All you need to do, is initialize Disqus once this component is mounted (and with proper parameters), and render element with specific ID, so that Disqus comment box can populate this element with actual code.

However, having Disqus script loaded asynchronously during my build process, I've encountered a case, in which my comments component is mounted, while there is no DISQUS object in the browser yet. This led to unusual behavior: I kept receiving e-mails about comments on this Disqus setup, but when I went to this very page, comments section was empty. Turns out, Disqus comments section on entry pages loaded properly after a while, but with it's basic setup, which is for the home page of my blog. All comments displayed and added were added, effectively, under soofka.pl URL in Disqus system. If someone managed to add a comment under URL of specific entry, it was not visible below this entry at all.

The best way to resolve this would be to wait for some information from Disqus itself, that it's ready. However, I've failed to find such event in their documentation, so I reverted to simple solution with timeout. My code attempts to setup Disqus with proper configuration within 3 seconds from mounting of comments component. It's displayed below. Note, that there is hard exit condition for this loop. Make sure, that your implementation has it too.

import * as React from 'react';

interface EntryCommentsPropsInterface {
  title: string;
  url: string;
  shortName: string;
  identifier: string;
}

declare const DISQUS: any;

export class EntryComments extends React.Component {

  private disqusSetupAttempts: number = 0;

  componentDidMount(): void {
    const { title, url, shortName, identifier } = this.props;

    const disqusSetupAttempt = setInterval(
      () => {
        if (typeof DISQUS !== 'undefined') {
          DISQUS.reset({
            reload: true,
            config() {
              this.page.title = title;
              this.page.url = window.location.href;
              this.page.shortName = shortName;
              this.page.identifier = identifier;
            },
          });
          clearInterval(disqusSetupAttempt);
        }

        this.disqusSetupAttempts += 1;
        if (this.disqusSetupAttempts >= 3) {
          clearInterval(disqusSetupAttempt);
        }
      },
      1000,
    );
  }

  render(): JSX.Element {
    return (
      <div id="disqus_thread"/>
    );
  }
}

export default EntryComments;

The only thing to keep in mind, is that the identifier parameter here should correspond to the identifier parameter set in global Disqus config.

Of course, it’s just the basic setup, and there are much more things that you can do with this powerful tool. For more advanced usage, I recommend checking Disqus developer documentation. But if you want to keep it simple, this short tutorial describes all you need.

Other blog posts

My first MobX store

2018-07 |

This content is only available in english

My first MobX store

My dad wants to read my blog. The only issue is that he doesn't speak English very well. It's communicative, but it's not quite enough to understand intricate, sophisticated Shakespearean language, I am decorating my posts with. Worry not, father, as I've found the solution: language versions. I am currently working on adaptations of my posts in Polish language. In the meantime, I'm also adapting my codebase to be able to recognize and properly handle language parameter. And for that purpose, for the first time, I decided to use MobX.

Continue reading

Webpack 4 config explained (with example)

2018-04 |

This content is only available in english

Webpack 4 config explained (with example)

Using a skeleton for your application prepared by someone else comes with great benefit of a lot of time saved, but also with huge cost of a lot of knowledge not obtained. Sometimes you'll manage to complete your assignment just fine with some predefined boilerplate, without too much need for deep investigation of it's nooks and crannies. Other times, you'll end up in a position, where you reverse engineer it in order to introduce some major change, or just give up and start from scratch with your own thing. I wouldn't like you to give up on my application skeleton. Thus, I'll describe some of it's shenanigans in it's documentation. Today, I'm explaining build process.

Continue reading

Hard to imagine, but it's over 1 year since I created this blog, and up until recently, it always had static head tags. Title always being the same, for example, wasn't that much of an issue to me, but social meta tags never related to the content of the post I'm sharing on Twitter, that was not cool (it's also not cool when it comes to SEO, but it's not that much of my concern right now). I finally had to tackle it. Here's a simple way to do it that I've found.

Continue reading

Back in the day, my JS projects were small and self-contained. Nowadays, in my professional work, majority, if not all of front-end applications I am working on are connected to multiple back-end services for variety of reasons. It gives me a freedom of not caring of the back-end, as long as we have defined a contract, and proceeding happily with what actually matters, i.e. colors and animations. But it also gave ma some headache, when I wanted to have pleasant, convenient coding environment on my localhost, and not have all of these weird back-end stuff running on my local machine as well. Here's how I worked it out with both Webpack Dev Server and Express.

Continue reading

When building web applications in React, I usually choose Express to be my server, and more often than not I use React-Router to manage redirections and changes in history. Not without a reason - both are among the most popular choices in their respective fields nowadays; both are simple and elegant in every day work. However, I had some tough moments with both of them when it came up to setting all unrecognized routing to "Not Found" page, and this piece came as a result of them.

Continue reading