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";56const BlogPost = ({ post }: InferGetStaticPropsType<typeof getStaticProps>) => {7 const router = useRouter();8 const utterancesRef = createRef<HTMLDivElement>();9 const [loading, setLoading] = useState(false);1011 useEffect(() => {12 const handleRouteChangeStart = () => {13 setLoading(true);14 };1516 const handleRouteChangeComplete = () => {17 setLoading(false);18 };1920 router.events.on("routeChangeStart", handleRouteChangeStart);21 router.events.on("routeChangeComplete", handleRouteChangeComplete);2223 return () => {24 router.events.off("routeChangeStart", handleRouteChangeStart);25 router.events.off("routeChangeComplete", handleRouteChangeComplete);26 };27 }, []);2829 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]);4445 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.