🏠 Back to home page
Using GitHub issues as a comment section
💬

Using GitHub issues as a comment section

Create a comment section with utterances and Next.js.

Daniell Wijdenbosch / May 13, 2021

2 min read847 views

ReactGuide

When I started writing this blog, I came across something very interesting:
 
Utterances allows you to embed comments on your website using GitHub's issue system, the comments are styled the same way you see on GitHub. Since my website is mainly focussed on informing developers, I thought this was the perfect tool since most developers already own a GitHub account.
I will continue to show you how you can set up utterances for your own website using Next.js. The first step is to install utterances as a GitHub App. This step should be very straightforward, do make sure you give utterances access to your repository.
There are several ways to initialise and configure utterances, I chose to map my document's title againt the title of a GitHub issue. Utterances takes care of displaying the comments, when somebody posts the first comment on a page, a new GitHub issue will be created.
Because switching between statically generated routes in Next.js does not give you the new document's title right away, I added route event handlers which update a loading state. When loading is true, I am removing the iframe element injected by utterances, otherwise I am loading the script which injects the iframe, this way we can always be sure the correct iframe is loaded when switching pages.
1import type { InferGetStaticPropsType } from "next";
2import { createRef, useEffect, useState } from "react";
3import { NextSeo } from "next-seo";
4import { useRouter } from "next/router";
5
6const BlogPost = ({ post }: InferGetStaticPropsType<typeof getStaticProps>) => {
7 const router = useRouter();
8 const utterancesRef = createRef<HTMLDivElement>();
9 const [loading, setLoading] = useState(false);
10
11 useEffect(() => {
12 const handleRouteChangeStart = () => {
13 setLoading(true);
14 };
15
16 const handleRouteChangeComplete = () => {
17 setLoading(false);
18 };
19
20 router.events.on("routeChangeStart", handleRouteChangeStart);
21 router.events.on("routeChangeComplete", handleRouteChangeComplete);
22
23 return () => {
24 router.events.off("routeChangeStart", handleRouteChangeStart);
25 router.events.off("routeChangeComplete", handleRouteChangeComplete);
26 };
27 }, []);
28
29 useEffect(() => {
30 if (loading) {
31 utterancesRef.current?.firstChild?.remove();
32 } else {
33 const scriptElement = document.createElement("script");
34 scriptElement.src = "https://utteranc.es/client.js";
35 scriptElement.async = true;
36 scriptElement.defer = true;
37 scriptElement.setAttribute("crossorigin", "annonymous");
38 scriptElement.setAttribute("repo", "daniellwdb/website");
39 scriptElement.setAttribute("issue-term", "title");
40 scriptElement.setAttribute("theme", "photon-dark");
41 utterancesRef.current?.appendChild(scriptElement);
42 }
43 }, [utterancesRef]);
44
45 return (
46 <>
47 <NextSeo title={`${post.icon} ${post.title}`} />
48 <h1>Comments</h1>
49 <div ref={utterancesRef} />
50 </>
51 );
52};
It's that simple! Utterances will now take care of displaying the comments, when somebody posts the first comment on a page, a new GitHub issue will be created.
 
What do you think? Leave your thoughts and questions below.

Not Playing

-

Spotify