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