Cross-posted articles
When an author publishes an article from the Scribe CMS to Bluesky, the Article object returned by @scribe-atp/core includes a bskyPostRef field. You can use this field to render a link to the Bluesky post — letting readers continue the conversation there.
The bskyPostRef field
Section titled “The bskyPostRef field”interface Article { // ...other fields bskyPostRef?: { uri: string; // AT URI of the Bluesky post — e.g. at://did:plc:.../app.bsky.feed.post/3mp... cid: string; // Content identifier of the post record };}bskyPostRef is only present on articles that the author has explicitly cross-posted to Bluesky from the CMS. Always check for its presence before using it.
Constructing the Bluesky post URL
Section titled “Constructing the Bluesky post URL”Bluesky post URLs follow a predictable pattern derived from the AT URI. An AT URI has the form:
at://{did}/{collection}/{rkey}The web URL for the same post is:
https://bsky.app/profile/{did}/post/{rkey}function bskyPostUrl(atUri: string): string { const parts = atUri.split('/'); const did = parts[2]; const rkey = parts[4]; return `https://bsky.app/profile/${did}/post/${rkey}`;}Rendering a “View discussion” link
Section titled “Rendering a “View discussion” link”Check for bskyPostRef before rendering. If the field is absent, the article was not cross-posted and there is no Bluesky post to link to.
function bskyPostUrl(atUri: string): string { const parts = atUri.split('/'); const did = parts[2]; const rkey = parts[4]; return `https://bsky.app/profile/${did}/post/${rkey}`;}
// In your article component:{article.bskyPostRef && ( <a href={bskyPostUrl(article.bskyPostRef.uri)} target="_blank" rel="noopener noreferrer"> View discussion on Bluesky </a>)}Creating a cross-post yourself
Section titled “Creating a cross-post yourself”Everything above covers reading an existing bskyPostRef — the common case for a site that just displays Scribe content. If you’re building your own publishing tool against the SDK (rather than using Scribe CMS’s own “Share to Bluesky” action), @scribe-atp/core exports crossPostToBluesky for creating the post in the first place.
This needs an authenticated AT Protocol agent for the author’s own account — it’s the one write operation in an otherwise read-only SDK.
import { crossPostToBluesky, buildCanonicalUrl } from '@scribe-atp/core';
const ref = await crossPostToBluesky(agent, { did: authorDid, documentUri: article.uri, documentCid: article.cid, publicationUri: site.uri, publicationCid: site.cid, canonicalUrl: buildCanonicalUrl(article, site), title: article.title, text: `New post: ${article.title}`, description: article.description,});
// ref → { uri: "at://did:plc:.../app.bsky.feed.post/3mp...", cid: "..." }// Write ref to the article's bskyPostRef field yourself if your tool// should be able to render the "View discussion" link afterward.See the API reference for the full CrossPostParams shape.
See also
Section titled “See also”- Social interactions — LikeButton, ShareButton, and SubscribeButton components
- Core Concepts — AT URIs and the Scribe data model