Webmentions on my blog, Part 2: Outgoing
2 min read
This is part 2 of my little webmentions series. In part 1, I outlined my incoming webmentions setup. This one will be much shorter because outgoing is a much more straightforward process.
As with incoming, I prefer to avoid dependencies on any external, third-party services to send my webmentions. I either want to self-host or roll my own. For outgoing webmentions, I decided to just roll my own.
And again, in the interest of full disclosure, I did use Claude Code to help me develop this.
The stack #
- Language: plain Node.js, CommonJS. One script, no framework.
fs/path: walk_site/and read the builtindex.htmlfiles.crypto: builds the content hash that flags a post as edited, so it re-sends.fetch(native, Node 18+): endpoint discovery and the webmention POSTs. No axios or got.jsdom: the one real dependency. Parses each page's HTML to pull the outgoing links and read the target'srel="webmention".- State: two flat JSON files, no database.
How it works #
So my homelab has a little build server that runs between 6 a.m. and 11 p.m. eastern. It checks every five minutes for new commits. If it finds none, it does nothing.
If it detects a new commit, it rebuilds the site, and for each recently built page, it hashes the content and its links, compares that to the last run's hash, and queues up a re-send of the webmentions for the links on that page.
Before we can send a webmention, we have to discover where to send it. So the system fetches the target page and finds the endpoint it advertises.
The discovery/send step has an SSRF (server-side request forgery) guard built into it. Just like with incoming webmentions, it's possible for a hostile actor to craft the webmentions link in such a way that would allow them to probe my servers and network.
Finally, it sends the webmention to the target and records the send: it stores the page's hash and the links it notified, so the next run can tell nothing changed and skip it.
One fun thing this has enabled is that I generate an RSS feed of successfully sent webmentions. I like to see how other people are displaying their webmentions so that's cool.
Conclusion #
And that's how my website receives and sends webmentions. What has your experience been with webmentions?
Leave a comment