The issue
When I first put this site on Gatsby, I found adding comments tricky. I used this blog post, Dynamic Comments with Gatsby and WordPress, tweaked it a bit and shoved it in. I only used it for the comments form because I wasn’t worried about rebuilding – I really just wanted to see how it worked.
But I didn’t understand it and I didn’t like wrapping my site in an ApolloClient, it seemed to slow it down a bit, and it all seemed a bit much to get not a lot of comments.
Enter this week as I’m doing something else and came across this page in the Gatsby docs, Build time and client runtime data fetching, and read about using fetch
. Fetch! I know how to use that. Well… I know how to use that with the WordPress REST API. And you know what? That will do.
A high level overview
I’m keeping the posts the same as before but dynamically loading comments and handling comment submissions using fetch
and the WordPress REST API.
When getting the comments, the fetch
requests are wrapped in useEffect
to get them after the page load, making sure to unsubscribe to the fetch
Promise, and I’m using useState
to set the comment list.
Submitting the comment is handled in an onclick
function which sends a POST request to the WordPress comments endpoint. I allow anonymous comments (and don’t have or want logged in users submitting comments) so there’s a tiny plugin with Gatsby helpers to which I’ve added a filter to allow anonymous comments which are off by default.
The details
There are a few components used.
Comments
: parent component for all comment related things (Comments gist here)CommentsList
: the list of all comments, usesComment
(CommentsList gist here)Comment
: the individual comment (Comment gist here)CommentCount
: the number of published comments on the post (CommentCount gist here)CommentForm
: the form for comment submission (CommentForm gist here)
I’ll explain the ones with the requests in detail here, Comments
and CommentForm
.
The Comments component
The entire component is at the end of this. It uses fetch
as an async function in useEffect
. This async function is immediately called to get the comments from the site. It’s done this way because useEffect
won’t take an async function like useEffect( async () => ...
so this needs to be inside the function it does use eg :