Skip to content

Building URLs

A Scribe Site record carries two URL-related fields that together define the root of the site’s content:

FieldExampleMeaning
site.url"anthonycregan.co.uk"The site’s domain (no protocol)
site.urlPrefix"blog"Path prefix for content — empty string if content is at the root

An article’s own slug lives in article.slug on an ArticleRef.

The canonical URL for a published article is:

https://{site.url}/{site.urlPrefix}/{group.slug}/{article.slug}

When urlPrefix is empty, the pattern is:

https://{site.url}/{group.slug}/{article.slug}

Write a small utility function once and reuse it across your app:

import type { Site } from '@scribe-atp/core';
function articleUrl(site: Site, groupSlug: string, articleSlug: string): string {
const base = site.urlPrefix
? `https://${site.url}/${site.urlPrefix}`
: `https://${site.url}`;
return `${base}/${groupSlug}/${articleSlug}`;
}

Usage:

const url = articleUrl(site, group.slug, article.slug);
// e.g. "https://anthonycregan.co.uk/blog/2024/my-first-post"
// or "https://norobots.blog/2024/my-first-post"

Pass the site’s canonical HTTPS URL directly to fetchSite — no slug derivation needed:

import { fetchSite } from '@scribe-atp/core';
await fetchSite('alice.bsky.social', 'https://alice.bsky.social');
await fetchSite('anthonycregan.dev', 'https://anthonycregan.co.uk');
await fetchSite('anthonycregan.dev', 'https://norobots.blog');

The toSlug utility is still exported from @scribe-atp/core for other uses, but it is no longer needed for site lookups.

An article’s human-readable slug is available directly on the ArticleRef object returned by fetchSite. Use article.slug — do not try to derive it from the AT URI.

const site = await fetchSite('alice.bsky.social', 'https://alice.bsky.social');
for (const group of site.groups) {
for (const article of group.articles) {
const url = articleUrl(site, group.slug, article.slug);
}
}

Article rkeys are opaque TIDs (e.g. 3mp47vvkh342n) assigned by the PDS. slugFromUri returns this TID, which is not the same as the human-readable slug. Prefer article.slug over slugFromUri when building URLs.