Introducing Bolt Comments
Posted 14 Jun 2021
While rebuilding my blog I ventured into the world of Jamstack. It's an interesting ecosystem but .NET presence is sorely lacking. So I did my part and built an integration between Statiq, a .NET Static Site Generator, and Kontent, a headless CMS with excellent .NET support.
Next up was adding comments. I was fully expecting there to by a range of open source solutions, but there isn't really. At least not anything I'd be comfortable either signing up for or hosting myself.
And... there definitely isn't anything .NET or Azure based. So I ended up rolling my own and called it Bolt Comments.
Requirements
- Privacy : I don't want to subject people on my site to 3rd party tracking.
- Technology : preferably .NET / Azure based, because that's what I know best
- Cheap : This is a personal site and... I'm Dutch, so obviously, cheap is important.
About privacy
I really don't like ads and absolutely do not want visitors to my site to get hooked and followed around. So no 3rd party tracking is allowed on this site (apart from the essential analytics of course). This already crosses off any major player in the commenting space like Disqus.
Inspiration
I looked around for similar open source projects and came across a Netlify project Jamstack Comments Engine. I really liked the simplicity of it, though it's not suitable for production usage imo. It is a pretty good hint at what a solution should look like.
That solution uses Netlify functions and stores it's data in Netlify forms. Azure has had Functions for quite a while, so I started scaffolding an API based on functions. The cheap and easy way to store data with functions is Azure Storage Tables. So I went with that. There are some nice bindings that work well with Storage Tables so that got me off to a good start.
Azure Static Web Apps
At some point I figured I needed an admin UI for this. I really wanted to make a nice looking app with decent UX so I decided to go for a React app. I know a fair bit of React and was looking forward to giving functional components a proper try.
Around the same time Azure Static Webapps was nearing completion and it's a pretty good fit for this project. It provides hosting for single-page apps and HTTP functions. It's pretty similar to Vercel and Netlify, but runs .NET code for the API code.
Connectivity
To make Bolt Comments really useful it needs to connect it to the outside world. When a new comment is posted I want to be notified. And since I'm using static static site generation to build this site, I want regenerate the site when comments are published. To limit complexity and integration points, I've added support for web hooks to handle these events.
Webhooks enable workflow services to trigger and send an e-mail provider or integrate with collaboration tools like Teams or Slack. Service like Zapier, ITTT or Pipedream make this really easy and are cheap too.
Security
Any app needs to be able to take some amount of abuse these days. Comments are essentially user contributed content, which means I need to be extra careful.
The easy catch is not to accept any <script> tags. So that'll just be rejected.
After some testing and playing around I decided to implement filtering on the posted comment to strip out tags that are outright dangerous or that can destroy your site layout.
In a nutshell, any content is first pulled through a Markdown processor to turn markdown into HTML. Then the HTML is filtered and purged. That is converted back to Markdown and stored.
Markdown inside
Even though comments are stored as Markdown internally, you get both Markdown and HTML in the API when you fetch comments. This allows both easy API integration (just stream the HTML into your app) and more flexible processing with a static site generator.
Auth
Authorization for the admin UI is handled by Azure Static WebApps. It provides easy self-managed auth using the most common login providers.
API calls to post or fetch comments also support an API key. That key is managed through the admin API.
Note thought that Azure Static WebApps currently do not support CORS for anything other than the static site itself. So when invoking the Bolt Comments API directly from a site, there has to be some sort of proxy to make the API call for your site.
Most Jamstack platforms offer a nice way to do that, for example Netlify has proxies that can inject the API key so you don't have to share that in your application.
Don't disclose the API key in your application. Use some sort of proxy to make API calls, for example using a .
Deployment
The holy grail to adoption of any software project, especially for open source, is how easy it is to get started. For a cloud project like Bolt Comments that means it should be dead simple to spin up an instance.
Unfortunately, this is where Azure Static Web Apps does not quite level up to competitors like Vercel and Netlify. Right now some manual steps are required but hopefully that'll change soon.
Conclusion
So I want something that's easy to host and safe for my visitors. I had a lot of fun building the app with Azure Functions and Azure Static Web Apps. If you're looking for a place to host your comments, please take Bolt comments for a spin and let me know what you think by leaving me a comment!