Adding Bluesky custom domain support to a Fresh app

Published on 5/25/2023 - less than a minute read (374 words, 770 tokens)

If you've been a web developer, you probably know about the .well-known standard, it's where you store things like:

  • ACME challege information if you are using the HTTP challenge for Let's Encrypt
  • Apple Pay metadata
  • Social network node information
  • WebFinger responses for Mastodon user discovery
  • Metadata for enrolment in Apple's mobile device management software

However, when you set up a custom username / domain name in Bluesky, you're supposed to set up a DNS TXT record pointing to your userid. But they do support fetching this information over HTTPS.

When I found about about this initially, I thought it would go in /.well-known/atproto or something to match the DNS record This would also prevent abuse and make it easier for operators of shared domains to prevent people from using their identity in social media, which could end in one of a thousand very bad things.


Turns out you're supposed to put it in this very memorable path: /xrpc/com.atproto.identity.resolveHandle, and then you return a JSON document that looks like this:


This is how this guy became S3, all of S3. That seems totally brand-friendly.

When I implemented Bluesky support for my new domain, I decided to do it over HTTPS for logistical reasons involving spacebar heating and my DNS setup being complicated.

Here's how you do it with Fresh:

Create a file called routes/xrpc/com.atproto.identity.resolveHandle.ts and copy these contents into it:

import { HandlerContext } from "$fresh/server.ts";

const myDID = "did:plc:g2ag3sguurbal7k6irnujf64";

export const handler = async (
  req: Request,
  _ctx: HandlerContext,
): Promise<Response> => {
  return new Response(JSON.stringify({ did: myDID }), {
    headers: {
      "Content-Type": "application/json",

Then deploy your app to production and follow the "change my handle" workflow so you can use your domain in the hellthread all you want. You can be or whatever your twisted heart desires.

If you want, you can follow me at I post irregularly there and I'm still trying to figure out my relationship with social media.

Share on Mastodon