The official account for the AT Protocol with a custom domain.
What's a custom domain?
A custom domain is a unique name that identifies a website on the internet. For example, Bluesky’s domain is blueskyweb.xyz
.
Every device that connects to the internet has a unique IP address that identifies it. But it’s much easier to remember blueskyweb.xyz
instead of a series of numbers. The Domain Name System (DNS) acts like a phonebook for the internet and points a domain like blueskyweb.xyz
to its IP address, so we don’t have to remember the numbers ourselves.
Domains can be further divided into subdomains. For example, if your domain was example.com
but you had a blog hosted at blog.example.com
, then blog
is the subdomain.
Why does Bluesky use domains as handles, and why would I want to use a domain as my handle?
Technically, it's the AT Protocol that lets you use domains as handles. Bluesky is a client application built on top of the protocol, so it will also use domains as handles.
The AT Protocol was designed to use domains for multiple reasons:
-
Identity: Bluesky is just one application built on top of the AT Protocol. Let’s say you set your handle to
example.com
on Bluesky. You’ll be able to use that same handle across all applications built on the AT Protocol (and there’s a growing number!). Now, you no longer have to list five different usernames based on what was available at the time you signed up for an app — just use your domain! -
Verification: Websites have a long history of verification already, so using domains borrows their authority. For example, a newsroom like NPR could set their handle to be
@npr.org
. Then, any journalists that NPR wants to verify could use subdomains to set their handles to be@name.npr.org
. Brand accounts could set their handle to be their domain as well, which companies like Vercel and Tailscale have already done.
- Portability: Maybe you want to switch to a different server. Then, there’s no need to switch your handle from something server-specific if you’re using your domain as your handle.
Read our previously published blog post on domain names as handles here for more information.
I'm convinced! How do I acquire a custom domain?
If you don't have a custom domain already, you can purchase one from any ICANN-accredited domain registrar or reseller. Note that this isn't required to join Bluesky; you could use our server’s off-the-shelf naming (in the format of @name.bsky.social
) if you prefer.
You can use services like Namecheap or Google Domains to register your domain of choice. Domains are unique, so you must choose one that hasn’t already been registered by someone else. During registration, you’ll likely pay an annual fee and provide personal information.
Your personal information is used to populate the WHOIS directory, which is a searchable database that holds information on domain ownership. You might prefer to keep your information private for various reasons — in that case, most domain registrars offer WHOIS privacy protection as a service.
How do I set this custom domain as my handle?
Let's use the Bluesky team’s @atproto.com
account as an example. Note that the account uses the handle @atproto.com
, which verifies its identity because it owns the website atproto.com.
Note: if you change your default Bluesky username (with the .bsky.social
suffix) to a custom domain, your old username will be available for someone else to use. However, any tags or mentions with your old handle will still point to your account.
The screenshots below will show you how to set your custom domain as your handle in your mobile app, but similar steps apply to the desktop version.
-
Open the left side menu by clicking your profile picture thumbnail. Click “Settings” and scroll down to the “Advanced” section. Click “Change my handle.”
-
On the “Change my handle” screen, click “I have my own domain.”
-
Now, you’ll have a screen that looks like this. This includes information that you will need to add to your domain registrar.
-
Navigate back to your domain registrar, which is the company you bought your domain from (Namecheap, Google Domains, etc.). The specific steps here depend on which company you used, but you’ll want to navigate to DNS management for your domain. This might be under an “Advanced DNS” tab.
Advanced: If you're using a hosting company other than the registrar, for example Cloudflare, navigate there to add your TXT record, not your original registrar.
-
We want to add a TXT (text) record to your domain. Step 3 above contains all of the information you’ll need to add to your domain. The DID value is public and not sensitive information. (Read more about DIDs here.)
- Set the domain:
_atproto
- Set the type: TXT
- Set the value field (also sometimes called “data”), except use your own DID value:
did=did:plc:[your value here]
- Set the domain:
-
After you add the TXT record, wait a couple of minutes for the change to propagate across the internet. Then, just click “Verify DNS Record.” You’re done! Check your Bluesky profile to see if it has updated. Remember, DNS propagation might take some time.
-
Congratulations, you have a custom domain as your handle now!
How can I set and manage multiple subdomain handles?
Organizations like newsrooms or companies may want to verify multiple affiliated individuals' accounts via subdomains. For example, a newsroom could set its journalists' handles to be @name.newsroom.com
. But managing many individual subdomains via TXT records can be cumbersome. In that case, you can use a non-DNS option by resolving multiple handles via HTTP under a .well-known
route.
This section is developer-friendly, and most organizations' tech teams are able to implement this easily. You can also reach us for assistance at support@bsky.app.
Instead of using DNS TXT records, you can return each account's DID from the route https://${handle}/.well-known/atproto-did
. The expected payload is a DID (such as did:plc:abcdef...
) with content-type text/plain
. The handle resolution function explicitly expects a HTTP 200 OK
status.
This is a code snippet for how handle resolution is implemented:
async function resolveHandle(handle: string) {
const res = await fetch(`https://${handle}/.well-known/atproto-did`)
const did = await res.text()
assert(typeof did === 'string' && did.startsWith('did:'))
return did
}
We're working on adding the ability to revalidate these handles periodically. For handles that get invalidated, all of the account's data will still be secure — the owner will not lose any posts, followers, etc. We will provide an in-app option to simply pick a new handle.
For more details about handle resolution and identity on the AT Protocol, please read more in our protocol documentation here.
Comments
0 comments
Article is closed for comments.