Overview
Headless blog publishing for AbsoluteJS. The package owns post contracts, publication metadata, feeds, sitemap routes, and browser hooks. Your application owns every element and every style.
@absolutejs/blogv0.1.0betaFrontend & UXHeadless, typed blog publishing primitives for AbsoluteJS: post registries, reading metrics, SEO metadata, feeds, sitemap routes, Elysia endpoints, and React hooks without bundled UI.
bun add @absolutejs/blogHeadless blog publishing for AbsoluteJS. The package owns post contracts, publication metadata, feeds, sitemap routes, and browser hooks. Your application owns every element and every style.
blog.all() returns published posts newest first. Drafts stay out of public lookups, feeds, and sitemap routes unless explicitly requested.
blog.head(post) returns canonical, Open Graph, Twitter, article meta, and BlogPosting JSON-LD values that can be passed to the AbsoluteJS Head component.
Mount all three standard feed formats with the optional Elysia plugin:
The literal paths preserve exact Elysia and Eden route inference:
/blog/rss.xml
/blog/atom.xml
/blog/feed.json
The core package also exports generateRssFeed, generateAtomFeed, and generateJsonFeed for applications that own their routes.
The React subpath contains hooks, not visual components:
Progress is measured against the article element instead of the entire document, so a site header and footer do not distort it.
Outcomes
Headless blog publishing for AbsoluteJS. The package owns post contracts, publication metadata, feeds, sitemap routes, and browser hooks. Your application owns every element and every style.
blog.all() returns published posts newest first. Drafts stay out of public lookups, feeds, and sitemap routes unless explicitly requested.
Mount all three standard feed formats with the optional Elysia plugin:
Hardening checklist
Follow in order
Working example for Define a blog.
import { createBlog, defineAuthor, definePost } from "@absolutejs/blog";
const author = defineAuthor({
id: "alex-kahn",
name: "Alex Kahn",
role: "AbsoluteJS",
});
const post = definePost({
author,
description: "Why provider differences belong in typed data.",
publishedAt: "2026-07-31",
slug: "why-citra-typed-oauth",
tags: ["OAuth", "TypeScript", "Citra"],
title: "Why Citra: Typed OAuth Without Provider Classes",
});
export const blog = createBlog({
posts: [post],
site: {
baseUrl: "https://absolutejs.com",
description: "Engineering notes from AbsoluteJS.",
name: "AbsoluteJS Blog",
publisher: {
name: "AbsoluteJS",
url: "https://absolutejs.com",
},
},
});blog.all() returns published posts newest first. Drafts stay out of public lookups, feeds, and sitemap routes unless explicitly requested.
blog.get("why-citra-typed-oauth");
blog.byTag("TypeScript");
blog.relatedTo(post);
blog.sitemapRoutes();
blog.head(post);Supported entry points declared by this project’s package manifest. Internal dist paths are not part of the package contract.
Public package entry point declared in package.json.
Scripts declared by this project’s package manifest.
Search the declarations exported by the current package type files. Expand a symbol to inspect its source-backed signature.
const generateRssFeed: (posts: readonly BlogPost[], site: BlogSite) => string;@absolutejs/blog