My last blog post was about my journey towards "getting rid" of Disqus as a comment provider, and moving over to hosting my comments on Github. The blog post was rather light on technical details, so here is the full technical walkthrough with code examples and all.
Since I already explained most of the reasoning and architectural choices in that post I will just go ahead with a step by step of the technical parts I think is interesting. If that means I end up skipping over something important, please let me know in the (Github) comments!
Step 0: Have a Gatsby.js site that pulls it's content from a Drupal site
This tutorial does not cover that, since many people have written such tutorials. As mentioned in my article "Geography in web page performance", I really like this tutorial from Lullabot, and Gatsby.js even has an official page about using Drupal with Gatsby.js.
Step 1: Create a repo to use for comments
The first step was to create an actual repository to act as a placeholder for the comments to be. It should be public, since we want anyone to be able to comment. I opted for the repo https://github.com/eiriksm/eiriksm.dev-comments. To create a repository on GitHub, you need an account, and then just visit https://github.com/new
Step 2: Associate blog posts with issues
The second step is to have a way to indicate which issue is connected to which blog post. Luckily I am still using Drupal, so I can just go ahead and create a field called "Issue id". Then, for each post I write, I create an issue on said repo, and take a note of the issue id. For example, this blog post has a corresponding issue at https://github.com/eiriksm/eiriksm.dev-comments/issues/6, so I just go ahead and write "6" in my issue id field.
Step 3: Fetch all the issues and their comments to Gatsby.js
This is an important part. To be able to render the comments at build time, the most robust approach is to actually "download" the comments and have them available in graphql. To do that you can try to use the source plugin for GitHub, but I opted for getting the relevant issues and comments and creating the source myself. Why, you may ask? Well the main reason is because then I can more easily control how the issue comments are stored, and by extension also store the drupal ID of the node along with the comments.
To achieve this, I went ahead and used the same JSONAPI source as Gatsby will use under the hood, and then I am fetching the issue comment contents of each of the nodes that has an issue ID reference. This will then go into the gatsby-node.js file, to make the data we fetch available to the static rendering. Something along these lines:
After we have set this up, we can build the site and start exploring the data in graphql. For example by running npm run develop, and visiting the graphql endpoint in the browser, in my case http://localhost:8000/___graphql:
This way we can now find Github comments with graphql queries, and filter by their Drupal ID. See example animation below, where I find the comments belonging to my blog post "Reflections on my migration journey from Disqus comments".
In the end I ended up with the following graphql query, which I then can use in the blogpost component:
This gives me all Github comments that are associated with the Drupal ID of the current page. Convenient.
After this it's only a matter of using this inside of the blog post component. Since this site mix and match comment types a bit (I have a mix of Disqus exported comments and Github comments), it looks something like this:
Step 4: Make it possible to fetch the comments client side
This is the part that makes it feel real-time. Since the above code with the graphql storing of comments only runs when I deploy this blog, comments can get quickly outdated. And from a UX perspective, you would want to see your own comment instantly after posting it. This means that even if we could rebuild and deploy every time someone posted a comment, this would not be instant enough to make sure a person actually sees their own comment. Enter client side fetching.
In the blog post component, I also make sure to do another check to github when you are viewing the page in a browser. This is because it is not necessary for the build step to fetch it once again, but I want the user to see the latest updates to the comments. So in the componentDidMount function I have something like this:
Step 5 (bonus): Substitute with Gitlab
Ressa asked in a (Github) comment on my last blogpost about doing this comment setup with Gitlab:
Do you know if something like this is possible with Gitlab?
Fair question. Gitlab is an alternative to Github, but differs in that the software it uses is itself Open Source, and you can self-host your own version of Gitlab. So let's see if we can substitute the moving parts with Gitlab somehow? Well, turns out we can!
The first parts of the project is the same: Create a field, have an account on Gitlab, create a repo for the comments. Then, to source the comment nodes, all I had to change was this:
As you might see, I took a shortcut and re-used some variables, meaning the graphql is querying against GithubComment. Which is a bad name for a bunch of Gitlab comments. But I think cleaning those things up would be an exercise for the reader. The last part with client side updates was not possible to do in a similar way. The API for that requires authenticating the request. Much like the above code from sourcing the comments. But while the sourcing happens at build time, client side updates happens in the browser. Which would mean that for this to work, there would be a secret token in your JavaScript for everyone to see. So that is not a good option. But it is indeed theoretically possible, and could for example be achieved with a small proxy server, or serverless function.
The even cooler part is that the exact same code also works for a self-hosted Gitlab instance. So you can indeed run open source software and own your own data with this approach. That being said, not using a server was one of the requirements for me, so that would defeat the purpose. In such a way, one might as well use Drupal as a headless comment storage.
I would still like to finish with it all working in Gitlab too though. In an animated gif, as I always end my posts. Even though you are not allowed to test it yourself (since, you know, the token is exposed in the JavaScript), I think it serves as an illustration. And feel free to (Github) comment if you have any questions or feel I left something out.
gitressa•Sunday, May 24th 2020 (about 5 years ago)
Awesome, thanks for taking the time to share how to set up hosting comments on Gitlab! It's always nice to have several options to choose between.
dasjo•Sunday, May 24th 2020 (about 5 years ago)
Interesting approach
ElijahLynn•Thursday, May 28th 2020 (about 5 years ago)
Gotta test this UX out... Thanks for the post!
ElijahLynn•Thursday, May 28th 2020 (about 5 years ago)
After I left the above comment, a
ctrl + R
refresh on the page didn't show the comment but actrl + shift + r
refresh (skip cache) did show it.I think a solution needs to be worked out so that a normal refresh shows new comments.
ElijahLynn•Thursday, May 28th 2020 (about 5 years ago)
But the comment above worked fine after clicking the link in the issue comment above. So 🤷.
eiriksm•Friday, May 29th 2020 (about 5 years ago)
Thanks for the feedback! I do actually have automated tests for making sure it does not need a ctrl shift r refresh, so it could be caching on the server level too? Of course, the test could give a false positive too :) I will do some testing myself as well...
Thanks again for commenting! 🤓
arafalov•Wednesday, Aug 12th 2020 (almost 5 years ago)
Interesting twist with live comments (I was waiting for the hook of some sort to trigger rebuild). But that means your home-page counts for the comments could be a bit out of sync with displayed counts on the page.
eiriksm•Wednesday, Aug 12th 2020 (almost 5 years ago)
Yes, very good point, that is true. The count will be a bit out of sync. The count was actually added after this article was written, so that is why it is not mentioned. But when a comment is posted on this repo, it triggers a rebuild of the blog, so it should be a matter of minutes 😄
Thanks for commenting!
Do you want to comment?
This article uses github for commenting. To comment, you can visit https://github.com/eiriksm/eiriksm.dev-comments/issues/6.