
Mastodon Comments in Publii
Table of Contents
Context (Publii)
For this website I'm using Publii, which ticks a lot of boxes for me personally:
- Generates a static HTML site,
- free & open source,
- easy to use,
- but not hiding any internals.
I had previously used 11ty, which I managed to wrestle into a usable state but never really "clicked" with me. this was also my previous experience with Jekyll, long ago. Publii makes a lot of sense for me, and I was comfortable enough with it to also try to extend it with a commenting system recently.
I know nothing about comment systems really, except that lots of places use Disqus. Unfortunately, the free tier forces ads, and thats a no from me. I was lucky enough to stumble upon a post from Grumpy Gamer referencing an article that suggests to use Mastodon threads as comments on a blog post. I liked the idea, but the blog post was incomprehensible to me.
Nonetheless, I thought trying to make mastodon comments work in my Publii set up would be a worthwhile way to spend an evening or two. Here's how I did it!
- I found someone whose already done it.
- Mostly I am writing this post so I can fix it later.
- Seriously, thanks to dpecos and Publii
mastodon-comments
Well, mostly. Earlier I said I know nothing about comment systems, and thats only half the truth. I know nothing about almost all web technologies. I went from Visual Basic straight to game engines - thank goodness. Web tech is weird and scary and pretty much the worst. So I googled someone who already did the work of retrieving a mastodon thread, figuring I could Macgyver it into Publii.
Github user dpecos has a great repo here - it's aptly named, and it seems to work great - well, mostly.
Javascript in Publii
This is fairly straightforward. if you open the File manager in publii (tools & plugins > File manager), you can drop the javascript file from the above repo right in there. now, the usage example in the mastodon-comments repo says you need a few <script = ......></script>
lines in a page's Head
before it'll work.
Already I'm lost, but poking around Publii allowed me to find the Custom HTML menu (tools & plugins > Custom HTML). This menu has a section called "Head", so I copied the recommended scripts (and the local mastodon-comments js file) into it. exactly like this:
<script src="mastodon-comments.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/2.4.1/purify.min.js" integrity="sha512-uHOKtSfJWScGmyyFr2O2+efpDx2nhwHU2v7MVeptzZoiC7bdF6Ny/CmZhN2AwIK1oCFiVQQ5DA/L9FSzyPNu6Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
Now if you inspect your rendered page in a browser's development tools, you should in fact see those script loads in every post's Head
- including this page!

now - according to the repo we sjhould be able to use this custom html to show our mastodon comments widget:
<mastodon-comments host="fosstodon.org" user="dpecos" tootId="109574160582937075" style="width : 1024px"></mastodon-comments>
When I did this, it did not work.
Updating mastodon-comments
Alright so debugging this was a pain because - again - I don't do web stuff, but the gist of it is that the link generated in the javascript was looking like https://null/@null/null
instead of https://mastodon.gamedev.place/@KPD/114061408372342674
. This was causing a smorgasbord of errors - and at least one CORS failure (I don't know what that is, but googling it further solidified my choice to not do web dev)
Googling around about WebElement lead me to this resolution - which worked, to my surprise. Changing
connectedCallback() {
this.innerHTML = `
<div id="mastodon-stats"></div>
<h3>Comments</h3>
<p>
<a class="link"href="https://${this.host}/@${this.user}/${this.tootId}">You can use your Fediverse (i.e. Mastodon, among many others) account to reply to this post</a>.
</p>
<p id="mastodon-comments-list"></p>
`;
to this:
connectedCallback() {
this.host = this.getAttribute("host");
this.user = this.getAttribute("user");
this.tootId = this.getAttribute("tootid");
this.innerHTML = `
<div id="mastodon-stats"></div>
<h3>Comments</h3>
<p>
<a class="link"href="https://${this.host}/@${this.user}/${this.tootId}">You can use your Fediverse (i.e. Mastodon, among many others) account to reply to this post</a>.
</p>
<p id="mastodon-comments-list"></p>
`;
Thats simply copy & pasting the three new lines - setting the local object's host, user & tootId to some attribute gets - from right above above that connectedCallback()
method. You can see them in the constructor, where apparently they simply do not work?
I have to imagine this is a result of some configuration difference between a more pure HTML page & however Publii is set up.
its also worth noting you can mess with the css in this file here to change the comments rendering - check out the solution in this issue if your site uses dark mode.
OK! Now it should work fine, and we can paste some javascript into each of our posts to generate a mastodon comment widget. Perhaps you - like me - find that to be distasteful & high-effort (it's not). Well - there's a bonus round.
Custom post Configs in Publii
I only want 1 comment section per post (...right?), and the only piece that's really changing is the tootId
, so we should be able to add that as a custom config for all posts. Effectively, if this post has a tootId
, use that tootId
to generate a comment widget. We can use Publii's custom post configs to provide data like this from the Publii WYSIWYG editor.

I found the config at /home/kyle/Documents/Publii/sites/kpd/input/themes/mono
which i guess decomposes to/home/kyle/documents/Publii/sites
being where Publii saves sites by default on Linux Mint. /kpd
is the site's name. /input
is the input data for generating the site, and my site uses the mono theme (/themes/mono
).
This config file is big, but there's an entry called "pageConfig": []
in there somewhere, and I added a config as follows:
{
"name": "mastoID",
"label": "Mastodon ID for comments",
"value": "",
"type": "text"
}
type is "text" so I can enter any text I want, everything else is fairly straightforward. This gives us the ability to assign a tootId
to each post.
Add the Widget to your Publii Theme's Template
having access to the tootId doesn't actually get us much. We need to make sure Publii triggers the mastodon-comments script when generating the page - with the tootId we provided, no less. In the same folder as the config file are some .hbs
files, which I guess is short for handlebars. One of these is post.hbs
, which is a template for how our posts get generated. I scanned mine for where it looked like my post content was placed, and managed to decipher the syntacx enough to add teh following:
{{#checkIf @config.post.mastoID '!=' ''}}
<h3>Mastodon</h3>
<mastodon-comments host="mastodon.gamedev.place" user="KPD" tootid="{{@config.post.mastoID}}" style="width : 512px"></mastodon-comments>
{{/checkIf}}
line by line:
- check if our post's mastoID config is not blank
- add a header 3 that says "Mastodon"
- trigger our call to
mastodon-comments
- use our post's
mastoID
config as thetootId
- use our post's
- end our if check
Thats All!
this isn't rocket science to a lot of folks but it was a lot of guessing & testing for me, as I almost never stray away from game dev. Once again, a huge thanks to dpecos for mastodon-comments and Publii for a great static site tool.
Maybe now I can figure out why my Table of Contents always have an empty slot at the beginning.