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!