**[Federated Replies and Reactions in Madblog](
https://blog.fabiomanganiello.com/article/Federated-repli… )**
**Engage with the Web from plain text files**
[Madblog](
https://git.fabiomanganiello.com/madblog ) is founded on a simple principle: a blog is just a collection of #markdown files in a folder. No databases, no logins, no client-side bloat — just files.
The recently implemented support for both [Webmentions](
https://blog.fabiomanganiello.com/article/webmentions-wit… ) and [ActivityPub](
https://blog.fabiomanganiello.com/article/Madblog-federat… ) add an extra appeal to this approach: now those text files can federate, they can send mentions to Wordpress blogs or Mastodon accounts, and you can visualize mentions, comments and reactions from other corners of the Web directly under your articles.
But after receiving in the past few days a bunch of reactions on [my blog](
https://blog.fabiomanganiello.com ) that I couldn't interact with, which forced me to fall back on [my standard Fediverse account](
https://manganiello.eu/@fabio ) to send replies and likes, I've decided to take the "[*everything is a file*](
https://en.wikipedia.org/wiki/Everything_is_a_file )" philosophy a step further.
Now from #madblog you can also **reply to comments** and **react to posts** across the Fediverse - all from plain text files in your content folder.
##
Replying to Comments
When someone comments on your article from Mastodon or another ActivityPub-compatible services, their message appears on your blog.
Now you can also respond directly from your blog.
Or you can reply to any other post on the Fediverse or mention anyone, without those posts cluttering your blog's front page (I've learned to avoid this fatal design mistake made by e.g. [Medium](
https://medium.com/ )).
###
How it works
Create a Markdown file under replies/<article-slug>/:
<span></span><code> [<span class="nl">//</span>]: <span class="na"># (reply-to:
https://mastodon.social/@alice/123456789)</span>
Thanks for the kind words, Alice! I'm glad the tutorial helped.
<span class="ni">@alice@mastodon</span>.social
</code>
Save the file, and Madblog automatically:
<li>Publishes your reply to the Fediverse as a threaded response</li>
<li>Notifies Alice on her Mastodon instance</li>
<li>Displays the reply on your blog, nested under her original comment</li>
Your reply lives in your content folder. Just like with your articles, you can version replies and reactions on git, synchronize them over [SyncThing](
https://syncthing.net/ ) or [Nextcloud Notes](
https://nextcloud.com/ ), or run some analysis scripts on them that would just operate on text files.
###
Replying to replies
Conversations can go as deep as you want. Reply to a reply by pointing reply-to at the previous message's URL:
<span></span><code> [<span class="nl">//</span>]: <span class="na"># (reply-to:
https://mastodon.social/@alice/123456790)</span>
Great question! I'll write a follow-up post about that.
<span class="ni">@alice@mastodon</span>.social
</code>
The threading is preserved both on your blog and across the Fediverse.
[[Example of a nested thread rendered on Madblog]( )]
(I hope that
@Julian Fietkau and
@wakest ⁂ won't mind for using a screenshot from their conversation on my blog 🙂)
###
Remember to mention your mentions
An important implementation note: if you're replying to someone else's ActivityPub post, it's important that you also mention them in the reply, otherwise your reply will be rendered under their comment but they may not be notified.
Usually you don't have to worry about this on Mastodon because the UI will automatically pre-fill the participating accounts in a sub-thread when you hit *Reply*.
But this is something to keep in mind when your posts are just text files.
##
Your replies are articles in their own right
Even though anything under replies/ won't appear on your blog's home page, it doesn't mean that it must be rendered just like a humble rectangle in a crowded comments section.
By clicking *View full reply* you get redirected to a separate page where the reply is rendered as a blog article, and its comments sections consists in the sub-tree of the reactions that spawned from that specific reply.
[[Example of a Madblog reply rendered as a blog article, with its own sub-thread of reactions]( )]
##
Liking Posts
Sometimes a reply is too much — you just want to show appreciation. Now you can "like" any post on the Fediverse with a simple metadata header.
###
Standalone likes
Create a file under replies/ with just a like-of header:
<span></span><code> [<span class="nl">//</span>]: <span class="na"># (like-of:
https://mastodon.social/@bob/987654321)</span>
</code>
This publishes a Like activity to the Fediverse. Bob sees the notification,
and your blog records the interaction.
###
Like and comment
Want to like *and* say something? Combine both:
<span></span><code> [<span class="nl">//</span>]: <span class="na"># (like-of:
https://mastodon.social/@bob/987654321)</span>
[<span class="nl">//</span>]: <span class="na"># (reply-to:
https://mastodon.social/@bob/987654321)</span>
This is such a great point! Bookmarking for later.
<span class="ni">@bob@mastodon</span>.social
</code>
Bob gets both the like and your reply as a threaded response.
##
Unlisted Posts
Not everything needs to appear on your blog's front page. Files under replies/ without reply-to and like-of headers become "unlisted" posts — they're published to the Fediverse but don't clutter your blog index.
Perfect for quick thoughts, threads, or conversations that don't warrant a full article.
<span></span><code> [<span class="nl">//</span>]: <span class="na"># (title: Thoughts of the day)</span>
Quick thought: I've been experimenting with writing all my Fediverse posts
as Markdown files. It's oddly satisfying to <span class="sb">`git log`</span> my social media history.
</code>
##
Guestbook Replies
Your blog's guestbook works the same way. Reply to guestbook entries by placing files under replies/_guestbook/:
<span></span><code> [<span class="nl">//</span>]: <span class="na"># (reply-to:
https://someone.blog/mention/123)</span>
<span class="ni">@alice@example</span>.com welcome! Thanks for stopping by.
</code>
##
Editing and Deleting
Changed your mind? Edit the file and an Update activity is sent. Delete the file and your reply is removed from the Fediverse too.
Accidentally liked something? Remove the like-of line (or delete the file) and an Undo Like is published.
Your content, your rules.
##
Getting Started
<li>Enable ActivityPub in your <code>config.yaml</code>:</li>
<span></span><code><span class="nt">link</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">
https://blog.example.com</span>
<span class="nt">enable_activitypub</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">true</span>
<span class="nt">activitypub_username</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">blog</span>
<span class="c1"># Only specify these if you want your ActivityPub domain to be different from your blog domain</span>
<span class="c1"># activitypub_link:
https://example.com</span>
<span class="c1"># activitypub_domain: example.com</span>
</code>
<li>Install Madblog</li>
<li>From <code>pip</code>:</li>
<span></span><code>pip<span class="w"> </span>install<span class="w"> </span>madblog
</code>
<li>From Docker:</li>
<span></span><code>docker<span class="w"> </span>pull<span class="w"> </span>quay.io/blacklight/madblog
</code>
<li>Run Madblog from your Markdown folder (it is recommended that your articles are stored under <code><data-dir>/markdown</code>):</li>
<li>From a <code>pip</code> installation:</li>
<span></span><code>madblog<span class="w"> </span>/path/to/data
</code>
<li>From Docker:</li>
<span></span><code>docker<span class="w"> </span>run<span class="w"> </span>-it<span class="w"> </span><span class="se">\</span>
<span class="w"> </span>-p<span class="w"> </span><span class="m">8000</span>:8000<span class="w"> </span><span class="se">\</span>
<span class="w"> </span>-v<span class="w"> </span><span class="s2">"/path/to/config.yaml:/etc/madblog/config.yaml"</span><span class="w"> </span><span class="se">\</span>
<span class="w"> </span>-v<span class="w"> </span><span class="s2">"/path/to/data:/data"</span><span class="w"> </span><span class="se">\</span>
<span class="w"> </span>quay.io/blacklight/madblog
</code>
<li>Any text file you create under <code>markdown/</code> becomes a blog article. Any text file you create under <code>replies/</code> becomes an unlisted post, a reply or a like reaction.</li>
Check the [README](
https://git.fabiomanganiello.com/madblog ) for detailed configuration options.
Happy blogging!