Bluesky Open Graph Tags

Which meta tags Bluesky reads and how they map to AT Protocol records

Tag priority order

CardyB resolves each card field using first-hit-wins fallback:

Card field Priority order
Title og:titletwitter:title<title>
Description og:descriptiontwitter:description<meta name="description">
Image og:imagetwitter:image

If nothing matches for a field, it’s left empty. A card with no title still renders using the URL as fallback text.

No twitter:card type support

Bluesky ignores twitter:card entirely. There’s no summary vs. summary_large_image distinction: all link cards render in the same format. You don’t need it, and setting it won’t change anything.

AT Protocol lexicon mapping

Card data gets written into the post record as an app.bsky.embed.external entry:

{
  "$type": "app.bsky.embed.external",
  "external": {
    "uri": "https://example.com/page",
    "title": "Page Title",
    "description": "Page description text",
    "thumb": {
      "$type": "blob",
      "ref": { "$link": "bafkrei..." },
      "mimeType": "image/jpeg",
      "size": 54321
    }
  }
}

The uri, title, and description are stored as plain text. The thumb is a blob reference, and the original og:image URL is not kept in the record. Once it’s baked into the post, it lives on the AT Protocol network independently of your server.

Recommended minimal setup

Standard Open Graph tags are all you need:

<meta property="og:title" content="Your Page Title">
<meta property="og:description" content="A brief description of your page.">
<meta property="og:image" content="https://example.com/image.jpg">

No Bluesky-specific meta tags exist. If you already have OG tags for other platforms, Bluesky uses them as-is.

og:image:width and og:image:height

Bluesky ignores og:image:width and og:image:height. The image is downloaded and processed regardless. These tags won’t cause issues; they’re just skipped.