The CardyB service
Bluesky doesn’t fetch link previews server-side. When you paste a link in the composer, the web app calls CardyB (https://cardyb.bsky.app/v1/extract?url=<url>), which fetches the page, parses Open Graph tags from the HTML, and returns structured card data to the client. The client then assembles the card locally.
The crawler user agent:
Mozilla/5.0 (compatible; Bluesky Cardyb/1.1; +mailto:support@bsky.app)
robots.txt token
CardyB respects robots.txt using the token BlueskyPreviewBot. If you block this token or have a blanket Disallow: /, no link cards will be generated.
User-agent: BlueskyPreviewBot
Allow: /
No JavaScript execution
CardyB fetches raw HTML only, with no headless browser or JS engine. Your OG tags need to be in the initial HTML response from the server, not injected by a client-side framework after page load.
Client-side implications
Because the client drives card generation (not Bluesky’s servers), a few things follow from this architecture:
- Third-party AT Protocol apps must implement the full pipeline: fetch HTML, parse OG tags, download and compress the image under 1 MB, upload the blob, and construct the
app.bsky.embed.externalrecord - Two posts to the same URL can show different previews if the page changed between posts
- There’s no background crawler retrying failed fetches. If it fails at post time, that’s it.
Checking if CardyB can reach your page
Test with curl using the CardyB user agent:
curl -A "Mozilla/5.0 (compatible; Bluesky Cardyb/1.1; +mailto:support@bsky.app)" https://example.com/your-pageIf you see your <meta> tags in the HTML response, CardyB will too.