Adding Comments to an Astro Blog with Giscus
After years of running a blog without comments, I finally decided it was time to add them. But not just any comment system - I had specific requirements in mind.
What I Wanted
My goals for a comment system were pretty straightforward:
- Free - No subscription fees or forced ads
- Portable - Not locked into a proprietary platform, ability to export my data
- Threaded conversations - Support for nested replies
- Secure - No sketchy third-party trackers or storing user credentials
- Moderated - Ability to delete spam and block bad actors
The last one was important. I didn’t want people posting links to spam or their latest get-rich-quick scheme on my blog.
The Options
There are a bunch of comment systems out there, but most didn’t fit the bill:
Disqus - Popular but the free tier has ads. Plus it’s a proprietary platform, so not exactly portable.
Custom solution - Build my own with a backend. Most flexible but way more infrastructure than I wanted to manage for a static site.
Utterances - Uses GitHub Issues to store comments. Free and portable, but GitHub Issues don’t support nested threading like I wanted.
Giscus - Uses GitHub Discussions to store comments. Free, portable, and supports threaded conversations. This looked promising..
Why Giscus Won
Giscus hit all my requirements:
- ✅ Free - Open source, no cost, no ads
- ✅ Portable - Comments stored in GitHub Discussions, can export via GitHub API
- ✅ Threads - Full nested reply support via GitHub Discussions
- ✅ Secure - Uses GitHub OAuth, backed by GitHub’s infrastructure
- ✅ Moderated - GitHub provides moderation tools (delete, hide, block users)
The bonus? Requiring a GitHub account to comment actually reduces spam. Most spammers won’t bother creating legitimate GitHub accounts.
The Implementation
Setting up Giscus was straightforward. First, I enabled GitHub Discussions on my repo and installed the Giscus GitHub App.
Then I visited giscus.app to configure it and get my repository ID and category ID. I added those to my constants:
// src/consts.ts - These are not secrets, just public IDs
export const GISCUS_REPO = "treymack/treymack.github.io";
export const GISCUS_REPO_ID = "MDEwOlJlcG9zaXRvcnkzODkwNDU3Ng==";
export const GISCUS_CATEGORY = "Announcements";
export const GISCUS_CATEGORY_ID = "DIC_kwDOAlGjAM4C1ypE";
I created a simple Astro component to wrap the Giscus widget:
---
// src/components/CommentsSection.astro
import {
GISCUS_REPO,
GISCUS_REPO_ID,
GISCUS_CATEGORY,
GISCUS_CATEGORY_ID,
} from "../consts";
---
<div class="comments-section mt-12 pt-8 border-t border-gray-200">
<h2 class="text-2xl font-bold mb-6">Comments</h2>
<script
is:inline
src="https://giscus.app/client.js"
data-repo={GISCUS_REPO}
data-repo-id={GISCUS_REPO_ID}
data-category={GISCUS_CATEGORY}
data-category-id={GISCUS_CATEGORY_ID}
data-mapping="pathname"
data-strict="0"
data-reactions-enabled="1"
data-emit-metadata="0"
data-input-position="top"
data-theme="light"
data-lang="en"
data-loading="lazy"
crossorigin="anonymous"
async></script>
</div>
A couple of key configuration choices:
data-mapping="pathname"- Each blog post URL gets its own discussiondata-loading="lazy"- Loads when scrolled into view for better performanceis:inline- Ensures the script runs properly with Astro’s view transitions
Then I just dropped the component into my blog post layout:
// src/layouts/PostLayout.astro import CommentsSection from
"../components/CommentsSection.astro"; // ... rest of layout ...
<article class="post-content prose prose-lg max-w-none">
<slot />
</article>
<CommentsSection />
That’s it! Every blog post now has comments automatically.
Moderation Workflow
For moderation, I enabled GitHub notifications for Discussions. Now I get an email whenever someone comments. If I spot spam or inappropriate content, I can:
- Hide the comment (removes from public view)
- Delete it permanently
- Block the user from commenting anywhere in my repo
- Lock the discussion if things get out of hand
GitHub also has built-in spam detection that flags suspicious accounts and known spam patterns, which helps catch the obvious stuff automatically.
The Gotcha
One thing to watch out for - make sure your category name matches your category ID. I initially had a mismatch where the configuration was pointing to “Comments” but the ID was for “Announcements”. Comments posted fine to GitHub Discussions, but they weren’t showing up in the widget because it was looking in the wrong category.
Are the IDs Secret?
Quick security note: the repository ID and category ID in the config are not secrets. They’re public identifiers that get exposed in the browser anyway when the Giscus script loads. They’re like your email address - they point to your resources but don’t grant access to them. Safe to commit to your public repo.
Worth It?
Absolutely. The whole setup took about an hour, and now I have a comment system that’s free, portable, secure, and easy to moderate. No ads, no tracking, no vendor lock-in.
If you’re running an Astro blog (or any static site) and want comments, give Giscus a shot. It just works.
Let me know in the comments if you have questions.. 😉
Comments