@scribe-atp/core
Functions
Section titled “Functions”fetchSite
Section titled “fetchSite”function fetchSite( author: string, publicationUrl: string, signal?: AbortSignal): Promise<Site>Fetches a site record from the author’s PDS. Resolves the author handle to a DID, discovers the PDS, and returns the full Site with embedded group and article metadata.
| Parameter | Type | Description |
|---|---|---|
author | string | Author handle (alice.bsky.social) or DID (did:plc:…) |
publicationUrl | string | The site’s canonical HTTPS URL, e.g. "https://alice.bsky.social" |
signal | AbortSignal | Optional. Cancel the request when the signal fires |
fetchArticleBySlug
Section titled “fetchArticleBySlug”function fetchArticleBySlug( author: string, publicationUrl: string, articleSlug: string, signal?: AbortSignal): Promise<ArticleResult>Fetches a full article record and its AT URI in a single call. Resolves the site record first (using the publication URL cache if already fetched), then locates the article ref by slug and fetches the full article.
| Parameter | Type | Description |
|---|---|---|
author | string | Author handle or DID |
publicationUrl | string | The site’s canonical HTTPS URL, e.g. "https://alice.bsky.social" |
articleSlug | string | The article’s rkey / slug |
signal | AbortSignal | Optional. Cancel the request when the signal fires |
Returns { article: Article, uri: string }. The uri is the full AT URI of the site.standard.document record — pass it to @scribe-atp/social’s LikeButton component.
This is the preferred function for article pages in server-rendered frameworks. Use fetchArticle only when you don’t need the AT URI.
fetchArticle
Section titled “fetchArticle”function fetchArticle( author: string, articleSlug: string, signal?: AbortSignal): Promise<Article>Fetches a single article record (including full HTML content) directly by slug. Does not return the AT URI.
| Parameter | Type | Description |
|---|---|---|
author | string | Author handle or DID |
articleSlug | string | The article’s rkey / slug |
signal | AbortSignal | Optional. Cancel the request when the signal fires |
resolvePublicationUri
Section titled “resolvePublicationUri”function resolvePublicationUri( author: string, publicationUrl: string, signal?: AbortSignal): Promise<string>Resolves the AT URI of a site record given the author handle and publication URL. Results are cached for the lifetime of the module — repeated calls with the same arguments make no additional network requests.
| Parameter | Type | Description |
|---|---|---|
author | string | Author handle or DID |
publicationUrl | string | The site’s canonical HTTPS URL |
signal | AbortSignal | Optional. Cancel the request when the signal fires |
Returns a string AT URI, e.g. "at://did:plc:.../site.standard.publication/3mp4nd46xwr2h". Pass this to @scribe-atp/social’s SubscribeButton component.
listSites
Section titled “listSites”function listSites( author: string, signal?: AbortSignal): Promise<SiteRecord[]>Returns all site records for the given author. Calls com.atproto.repo.listRecords for the site.standard.publication collection and follows cursor pagination automatically.
| Parameter | Type | Description |
|---|---|---|
author | string | Author handle (alice.bsky.social) or DID (did:plc:…) |
signal | AbortSignal | Optional. Cancel the request when the signal fires |
Each SiteRecord is a Site with an additional uri field (the full AT URI of the record). Use slugFromUri(record.uri) to extract the rkey when you need to construct URLs.
listArticles
Section titled “listArticles”function listArticles( author: string, signal?: AbortSignal): Promise<ArticleRef[]>Returns all published article records for the given author as lightweight ArticleRef objects (no content field). Calls com.atproto.repo.listRecords for the site.standard.document collection and follows cursor pagination automatically.
| Parameter | Type | Description |
|---|---|---|
author | string | Author handle or DID |
signal | AbortSignal | Optional. Cancel the request when the signal fires |
Call fetchArticle to retrieve the full content for any article.
toSlug
Section titled “toSlug”function toSlug(domain: string): stringDerives a slug from a domain name by replacing . with - and removing non-alphanumeric characters.
toSlug('norobots.blog') // → "norobots-blog"toSlug('anthonycregan.co.uk') // → "anthonycregan-co-uk"toSlug is no longer needed for SDK calls — fetchSite, fetchArticleBySlug, and resolvePublicationUri now take a full HTTPS URL instead of a slug. It remains exported for any other use where slug-style strings are useful.
slugFromUri
Section titled “slugFromUri”function slugFromUri(uri: string): stringExtracts the rkey (slug) from an AT URI.
slugFromUri('at://did:plc:abc/site.standard.document/my-post') // → "my-post"flattenArticles
Section titled “flattenArticles”function flattenArticles( groups: Array<{ articles: ArticleRef[] }>): ArticleRef[]Flattens all ArticleRef objects from all groups into a single ordered array.
const allArticles = flattenArticles(site.groups);generateFeed
Section titled “generateFeed”function generateFeed(site: Site, options: FeedOptions): stringReturns a complete RSS 2.0 XML string for all published articles in the site.
FeedOptions
| Property | Type | Required | Description |
|---|---|---|---|
baseUrl | string | Yes | Your site’s origin, e.g. "https://alice.example.com" |
feedUrl | string | No | Canonical URL of the feed — used for the <atom:link> self-reference |
language | string | No | RSS <language> tag. Default: "en" |
limit | number | No | Maximum number of items to include |
See the RSS feeds guide for usage examples.
getSitemapEntries
Section titled “getSitemapEntries”function getSitemapEntries( site: Site, options: GetSitemapEntriesOptions): SitemapEntry[]Returns an array of sitemap entries for all published articles (plus the site root and group index pages).
GetSitemapEntriesOptions
| Property | Type | Required | Description |
|---|---|---|---|
baseUrl | string | Yes | Your site’s origin, e.g. "https://alice.example.com" |
SitemapEntry
interface SitemapEntry { url: string; lastmod?: string; // ISO 8601 date, e.g. "2024-03-15"}See the Sitemaps guide for usage examples.
generateArticleMeta
Section titled “generateArticleMeta”function generateArticleMeta(article: Article, site: Site): ScribeMetaTag[]Returns a framework-neutral array of meta tag descriptors for an article page. Covers og:type, og:title, og:url, og:site_name, og:description, og:image, twitter:card, twitter:title, twitter:description, and twitter:image.
| Parameter | Type | Description |
|---|---|---|
article | Article | The full article object, as returned by fetchArticleBySlug or fetchArticle |
site | Site | The site object, used for og:site_name and canonical URL derivation |
Pass the output to a framework adapter (articleMeta in @scribe-atp/react-router-framework, articleMetadata in @scribe-atp/next, articleSeoMeta in @scribe-atp/nuxt) or convert to your framework’s format manually.
See the Open Graph meta tags guide for framework-specific usage.
generateSiteMeta
Section titled “generateSiteMeta”function generateSiteMeta(site: Site): ScribeMetaTag[]Returns meta tag descriptors for a site index or group page — covers title, og:type (website), and optionally description and splash image.
| Parameter | Type | Description |
|---|---|---|
site | Site | The site object |
buildCanonicalUrl
Section titled “buildCanonicalUrl”function buildCanonicalUrl(article: Article, site: Site): stringDerives the fully-qualified canonical URL for an article. Uses article.canonicalUrl if set; otherwise combines site.url (the site’s domain, e.g. "myblog.com"), site.urlPrefix, and article.path to produce an https:// URL.
buildCanonicalUrl(article, site);// → "https://alice.bsky.social/blog/my-first-post"interface Site { title: string; url: string; // Domain without protocol, e.g. "alice.bsky.social" urlPrefix: string; // Path prefix, e.g. "blog" — empty string if content is at root description?: string; splashImageUrl?: string; logoImageUrl?: string; groups: SiteGroup[]; ungroupedArticles: ArticleRef[];}SiteGroup
Section titled “SiteGroup”interface SiteGroup { slug: string; title: string; articles: ArticleRef[];}ArticleRef
Section titled “ArticleRef”A lightweight snapshot of article metadata, embedded in the site record to avoid N+1 fetch patterns. Does not include content.
interface ArticleRef { uri: string; // AT URI, e.g. "at://did:plc:…/site.standard.document/my-post" title: string; slug?: string; // Article slug / rkey splashImageUrl: string | null; description?: string | null; tags?: string[]; createdAt: string; // ISO 8601 publishedAt?: string; // ISO 8601 updatedAt?: string; // ISO 8601}Article
Section titled “Article”The full article record, including HTML content. Returned by fetchArticle.
interface Article { title: string; content: string; // Sanitised HTML — safe to render directly textContent?: string; // Plain-text version of content (HTML tags stripped) path: string; // e.g. "/creative-writing/my-post" site: string; // AT URI of the publication, e.g. "at://did:plc:…/site.standard.publication/3abc" canonicalUrl?: string; // Fully-qualified article URL, e.g. "https://myblog.com/blog/my-article" coverImageUrl?: string; // URL of the cover/splash image description?: string; tags?: string[]; contributors?: ArticleContributor[]; bskyPostRef?: { uri: string; cid: string }; // Bluesky post reference if the article was cross-posted createdAt?: string; // ISO 8601 publishedAt: string; // ISO 8601 updatedAt: string; // ISO 8601}ArticleContributor
Section titled “ArticleContributor”Additional contributors on a published article. Populated via Scribe CMS when the contributor invitation flow is in place; an empty array is written on first publish.
interface ArticleContributor { did: string; // AT Protocol DID of the contributor role?: string; // e.g. "author", "editor", "illustrator" displayName?: string; // Human-readable name}SiteRecord
Section titled “SiteRecord”A Site with the AT URI of its underlying record included. Returned by listSites.
interface SiteRecord extends Site { uri: string; // AT URI, e.g. "at://did:plc:…/site.standard.publication/3mp4nd46xwr2h"}Use slugFromUri(record.uri) to extract the rkey when constructing URLs.
ArticleResult
Section titled “ArticleResult”Returned by fetchArticleBySlug. Contains the full article and its AT URI.
interface ArticleResult { article: Article; uri: string; // AT URI, e.g. "at://did:plc:…/site.standard.document/3abc123"}ScribeMetaTag
Section titled “ScribeMetaTag”The output element type of generateArticleMeta and generateSiteMeta. A union of three tag shapes:
type ScribeMetaTag = | { title: string } | { name: string; content: string } | { property: string; content: string };Framework adapters convert this to their own meta format. Consume it directly only if you’re writing your own adapter or using a framework not covered by the existing packages.