Live demo of the Mastodon comment renderer that ships with basalt. Scroll to the bottom and the thread populates from the instance's public API. If you turn JavaScript off, nothing loads but the link still works.
How the renderer behaves
Opt-in per post via front matter:
+++
comments = "mastodon"
mastodon = "https://your.server/@handle/123456789"
+++The template at templates/partials/comments.html checks page.extra.comments, emits an empty <section id="comments"> with a data-url attribute, then stops. No API call fires during page render.
The small comments-loader.js sets up an IntersectionObserver on #comments. When the section scrolls into view, it dynamically imports the platform-specific renderer: either comments-mastodon.js or comments-bluesky.js. Nothing else runs until the reader gets there.
The Mastodon renderer hits GET /api/v1/statuses/:id/context, reads the descendants array, and renders a nested tree in the same mono type as the rest of the site. HTML content is sanitized with DOMPurify, inlined on first use and cached afterwards.
What you pay for
Nothing, until you scroll. On pages without the comments = "mastodon" front-matter, none of the comment scripts ship. On pages that do, the loader is about 300 bytes and the renderer is about 4kb, plus DOMPurify at about 22kb on first use. DOMPurify is the biggest single cost; I'm open to suggestions for a smaller sanitiser.
No tracking pixels, no cookies, no third-party iframes, no consent banner. The embedded thread is a plain DOM tree drawn from a public API response.
Alternative flavours
Prefer Bluesky? There's a sister demo post with the same flow against app.bsky.feed.getPostThread. The loader picks the renderer by the data-platform attribute on #comments, so swapping platforms is a one-line front-matter change.
Scroll down. The fediverse should do its thing in a moment.
Reply on mastodon ↗