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.
There are a few components used.
Comments: parent component for all comment related things (Comments gist here)
CommentsList: the list of all comments, uses
Comment(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,
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 :