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

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

Moving from Sass to Styled Components (with snapshot tests)

2018-08 |

This content is only available in english

Moving from Sass to Styled Components (with snapshot tests)

Who doesn't like to constantly rework perfectly fine stuff into something new and fancy just because it's trendy now? Well, probably pretty much every single JS developer, most certainly everyone who works with this language long enough to experience at least a glimpse of famous "JS fatigue" feeling (so approximately a few weeks). However, I created this blog as a playground to try out new libraries and frameworks, and since I'm learning Styled Components for my professional work at the moment, even though Sass-based styling worked perfectly for my needs, I reimplemented all of it into this controversial CSS-in-JS. And I'm still sane!

Continue reading

How to set up tooling around your open source project

2019-11 |

This content is only available in english

How to set up tooling around your open source project

Lately in my project we had very particular need for specific validation of content of JavaScript bundle produced by Webpack. In the process of extensive research we have not found any existing tool to serve this purpose. Therefore, I've created Webpack Bundle Content Validator, which is a Webpack plugin and a CLI tool for Webpack bundle content validation. More importantly, I made it open source. Surprisingly, simply publishing it to NPM wasn't enough - I decided to set up continuous integration, automated unit tests code coverage calculation, automated check for vulnerabilities and a few other things, in order to make it legitimate and reliable package. In this post I'm describing those steps in details.

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

Syntax highlighting in React with highlight.js and Web Worker

2018-09 |

This content is only available in english

Syntax highlighting in React with highlight.js and Web Worker

One of the most common issues I heard people have with my blog was lack of syntax highlighting in posts, especially those, which contain a lot of code. Okay, it's almost 2019, I'm a software engineer, working mostly with front-end these times - I finally agreed, that it should be added. So I added it. And in the meantime, I also learned a little bit about Web Workers. Hence, this post, in which I describe this little adventure.

Continue reading