← Back to Blog | adding comments on my blog with bluesky
| Talor AndersonThis blog now has commenting powered by bluesky!
I like bluesky a lot as an app. I think their decentralized model is cool: I have the handle @talor.computer not because I happened to get that username on their site first but because I own the domain name https://talor.computer.
All data on the site is freely accessible and easy to retrieve by simple APIs. Very different than X/Twitter's extremely locked down, expensive-to-the-point-of-not-existing API.
Because you can look up the data for any post, including replies, Bluesky ends up being a great way to build a comments feature into your site, where replies under a certain bluesky post show up as comments under your blog!
Here's the tutorial I followed, modified slightly to fit my own blog, for how to set this up.
In my blog post editor, I added a helper that lets me paste a link to a bluesky post, and then it transforms it automatically into a did
and cid
pair (identifiers needed to look up the post from the API).
export interface BlueskyPostInfo {
did: string;
cid: string;
}
export function parseBlueskyUrl(
url: string
): { handle: string; cid: string } | null {
try {
const urlObj = new URL(url);
// Match pattern: https://bsky.app/profile/{handle}/post/{cid}
const match = urlObj.pathname.match(
/^\/profile\/([^\/]+)\/post\/([^\/]+)$/
);
if (!match) {
return null;
}
const [, handle, cid] = match;
return { handle, cid };
} catch {
return null;
}
}
export async function resolveBlueskyHandle(
handle: string
): Promise<string | null> {
try {
const response = await fetch(
`https://public.api.bsky.app/xrpc/com.atproto.identity.resolveHandle?handle=${encodeURIComponent(handle)}`
);
if (!response.ok) {
return null;
}
const data = await response.json();
return data.did;
} catch {
return null;
}
}
export async function convertBlueskyUrl(
url: string
): Promise<BlueskyPostInfo | null> {
const parsed = parseBlueskyUrl(url);
if (!parsed) {
return null;
}
const did = await resolveBlueskyHandle(parsed.handle);
if (!did) {
return null;
}
return {
did,
cid: parsed.cid,
};
}
Hopefully this will get me some traction on my posts over there: I've been growing a decent following on X/Twitter, but don't see much engagement on bluesky yet.
Leave a comment if you see this!