Blog comments with GitHub

February 21, 2020

-


As I’m using GitHub in many aspects for this blog (is hosted by GitHub pages and most of the experiments information is being fetched from GitHub), using Disqus to manage post comments felt out of place.

Recently, looking at how fastpages manages comments, I noticed the use of Utterances. This great tools allows to use GitHub issues to manage blog comments 😃, let’s look at how we can incorporate it as a React component (the code here was inpired by this post).


Comments component

First, we need to create a Comments component that we can add to any page. This will serve as a container for the Utterances component we will create in the next step:

// Comments.js
import React, { useRef } from 'react';
import Utterances from './Utterances';

const Comments  () => {
  const ref = useRef();

  return (
    <div>
      <Utterances repo='yourGitUser/yourGitRepo' ref={ref} />
    </div>
  );
};

export default Comments;

Utterances component

The Utterances component needs to receive the repository location repo and a reference ref. Note the use forwardRef, since we are not using React to create the DOM element that will hold the Utterances script:

// Utterances.js
import React, { useEffect, forwardRef, useState } from 'react';

const Utterances = forwardRef( ( { repo }, ref ) => {
  const [ status, setStatus ] = useState('pending');

  useEffect(() => {
    const script = document.createElement('script');
    script.onload = () => setStatus('success');
    script.onerror = () => setStatus('failed');
    script.async = true;
    script.src = 'https://utteranc.es/client.js';
    script.setAttribute('repo', repo);
    script.setAttribute('issue-term', 'pathname');
    script.setAttribute('theme', 'github-light');
    script.setAttribute('crossorigin', 'anonymous');
    ref.current.appendChild(script);
  }, [ ref ])

  return (
    <div>
      {status === 'failed' && <div>Error. Please try again.</div>}
      {status === 'pending' && <div>Loading script...</div>}
      <div ref={ref} />
    </div>
  );
});

export default Utterances;

You can check all configuration parameters on Utterances website.


Using it

Finally, to use it just import the component and place it in your layout. This is how I use it on my blog post template:

// blog-post.js
// ...
import Comments from '../components/Comments';
// ...

const BlogPostTemplate = () => {
  // ...

  return (
    <div>
      {/* ... */}
      <Comments />
    </div>
  );
};

Cheers!
Loading script...