Blog namespace
Reference for blog posts, tags, authors, adjacent posts, related posts, and search.
A
JUse board.blog to render published posts, tag and author archives, adjacent navigation, related content, and search. These reads are public; your frontend owns routes, layout, metadata, and safe rendering of the returned HTML. Check board.context().features.blog before exposing blog navigation.
Shared behavior
Every method returns the Board API wire body unchanged and throws BoardApiError for a non-2xx response. The final FetchOptions argument passes abort signals, headers, and framework cache directives through to fetch.
List and search envelopes include object, url, hasMore, nextCursor, and data. Post lists return PublicBlogPostSummary; only a post detail includes its html body and SEO fields.
board.blog.posts.list
List published posts, newest first.
1234board.blog.posts.list(query?: BlogPostsListQuery,options?: FetchOptions,): Promise<ListEnvelope<PublicBlogPostSummary>>
| Field | Type | Behavior |
|---|---|---|
cursor | string | Opaque cursor from nextCursor. |
limit | number | Page size from 1 to 100. |
tagSlug | string | Restrict posts to one tag. |
authorSlug | string | Restrict posts to one author. |
featured | 'true' | Restrict the list to featured posts. |
123456789const page = await board.blog.posts.list({tagSlug: 'product-news',featured: 'true',limit: 12,});for (const post of page.data) {console.log(post.title, post.slug, post.publishedAt);}
Summaries contain identity, title/slug, featured state, images, excerpt, reading time, publish/canonical dates, authors, and tags. They do not contain html. A missing/private board returns 404.
Related methods: board.blog.posts.retrieve, board.blog.tags.retrieve, and board.blog.authors.retrieve.
board.blog.posts.retrieve
Retrieve one published post by slug.
12345board.blog.posts.retrieve(postSlug: string,query?: Record<string, never>,options?: FetchOptions,): Promise<PublicBlogPost>
1234567const post = await board.blog.posts.retrieve('launching-acme-jobs');if (post.redirected && post.newSlug) {console.log('Redirect permanently to:', post.newSlug);}console.log(post.title, post.html);
The detail adds html, ogImageUrl, featureImageCaption, seoTitle, seoDescription, redirected, and newSlug to the summary. When a historical slug resolves, emit a permanent redirect to newSlug rather than rendering duplicate content. html can be null; the frontend must own its empty state and rendering policy.
A missing board or post returns blog_post_not_found with status 404.
Related methods: board.blog.posts.adjacent, board.blog.posts.similar, and the SEO guide.
board.blog.posts.adjacent
Retrieve the previous older post and next newer post by publish date.
1234board.blog.posts.adjacent(postSlug: string,options?: FetchOptions,): Promise<PublicBlogAdjacentPosts>
1234const adjacent = await board.blog.posts.adjacent('launching-acme-jobs');console.log('Older:', adjacent.previous?.slug ?? 'none');console.log('Newer:', adjacent.next?.slug ?? 'none');
Either previous or next can be null at the ends of the archive. A missing board or source post returns blog_post_not_found with status 404.
Related method: board.blog.posts.retrieve.
board.blog.posts.similar
Return published posts related to one post. The source post is excluded.
12345board.blog.posts.similar(postSlug: string,query?: BlogSimilarQuery,options?: FetchOptions,): Promise<ListEnvelope<PublicBlogPostSummary>>
query.limit accepts 1–20 and defaults to 6.
1234567const related = await board.blog.posts.similar('launching-acme-jobs', {limit: 6,});for (const post of related.data) {console.log(post.title);}
An empty data array is valid. A missing board/post returns 404. Similarity infrastructure failure returns search_unavailable with status 503.
Related method: board.blog.posts.retrieve.
board.blog.tags.list
List all public, non-internal tags.
1234board.blog.tags.list(query?: Record<string, never>,options?: FetchOptions,): Promise<ListEnvelope<PublicBlogTag>>
12345const tags = await board.blog.tags.list();for (const tag of tags.data) {console.log(tag.name, tag.slug);}
Each PublicBlogTag contains id, name, slug, description, and the public_blog_tag discriminator. A missing/private board returns 404.
Related methods: board.blog.tags.retrieve and board.blog.posts.list.
board.blog.tags.retrieve
Retrieve one public tag by slug.
12345board.blog.tags.retrieve(tagSlug: string,query?: Record<string, never>,options?: FetchOptions,): Promise<PublicBlogTag>
1234const tag = await board.blog.tags.retrieve('product-news');const posts = await board.blog.posts.list({ tagSlug: tag.slug });console.log(tag.name, posts.data.length);
A missing board or tag returns blog_tag_not_found with status 404.
Related method: board.blog.posts.list.
board.blog.authors.list
List active blog authors.
1234board.blog.authors.list(query?: Record<string, never>,options?: FetchOptions,): Promise<ListEnvelope<PublicBlogAuthor>>
12345const authors = await board.blog.authors.list();for (const author of authors.data) {console.log(author.name, author.slug);}
Each author contains identity, name/slug, bio, avatar, website, and supported social URLs. A missing/private board returns 404.
Related methods: board.blog.authors.retrieve and board.blog.posts.list.
board.blog.authors.retrieve
Retrieve one active author by slug.
12345board.blog.authors.retrieve(authorSlug: string,query?: Record<string, never>,options?: FetchOptions,): Promise<PublicBlogAuthor>
1234const author = await board.blog.authors.retrieve('jane-doe');const posts = await board.blog.posts.list({ authorSlug: author.slug });console.log(author.name, posts.data.length);
A missing board or author returns blog_author_not_found with status 404.
Related method: board.blog.posts.list.
board.blog.search
Search published posts by free text.
12345board.blog.search(body: BlogSearchBody,query?: Record<string, never>,options?: FetchOptions,): Promise<SearchEnvelope<PublicBlogPostSummary>>
BlogSearchBody.query is required and accepts up to 200 characters. Optional cursor continues a result set and limit accepts 1–50.
12345678910const controller = new AbortController();const results = await board.blog.search({ query: 'launch marketing', limit: 10 },undefined,{ signal: controller.signal },);for (const post of results.data) {console.log(post.title, post.slug);}
This is a POST read. It returns post summaries rather than detail HTML. A missing/private board returns 404; handle validation failures and unavailable search infrastructure through BoardApiError.
Related methods: board.blog.posts.list and board.blog.posts.retrieve.