{"_id":"@absolutejs/blog","_rev":"2-1c3d9d88e5f51d16f3026b5434e558c7","name":"@absolutejs/blog","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@absolutejs/blog","version":"0.1.0","keywords":["absolutejs","blog","content","rss","atom","json-feed","seo","elysia","react"],"author":{"name":"Alex Kahn"},"license":"BSL-1.1","_id":"@absolutejs/blog@0.1.0","maintainers":[{"name":"alexkahndev","email":"alexkahn2019@gmail.com"}],"homepage":"https://github.com/absolutejs/blog","bugs":{"url":"https://github.com/absolutejs/blog/issues"},"dist":{"shasum":"7c177ada85fb5965d23303679054fb269e414f85","tarball":"https://registry.npmjs.org/@absolutejs/blog/-/blog-0.1.0.tgz","fileCount":22,"integrity":"sha512-myAUzhEkf57JeVEtR7WIiQBGIBMn0pE4Bxby2oTJ4m0kI6Kwx/A1ZvO8Ev2ZqAgnlG5za6g7JPpTwbE16Ei1gA==","signatures":[{"sig":"MEUCIFdOU8QyFQl3+zOcE+FkTI8IgoRRVvySV3wUAB2yLkgEAiEA1COTHUeKOtBXn75PzfSuwEZhv4ZmiIb4sZgfr/pZobM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":88255},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./react":{"types":"./dist/react.d.ts","import":"./dist/react.js","default":"./dist/react.js"},"./elysia":{"types":"./dist/elysia.d.ts","import":"./dist/elysia.js","default":"./dist/elysia.js"},"./manifest":{"types":"./dist/manifest.d.ts","import":"./dist/manifest.js","default":"./dist/manifest.js"},"./package.json":"./package.json","./manifest.json":"./dist/manifest.json"},"gitHead":"bf024185aa9ea1a8be62ea22274ff462bfddcbfe","scripts":{"test":"bun test tests/","build":"rm -rf dist && bun build src/index.ts src/elysia.ts src/react.ts src/manifest.ts --outdir dist --root ./src --sourcemap --target=browser --external react --external 'react/*' --external elysia --external 'elysia/*' --external @absolutejs/manifest --external '@absolutejs/manifest/*' --external @sinclair/typebox --external '@sinclair/typebox/*' && tsc --project tsconfig.build.json && absolute-manifest emit","format":"prettier --write \"./**/*.{ts,json,md}\"","release":"bun run check:package && npm publish --access public","typecheck":"tsc --noEmit","check:package":"bun run format && bun run typecheck && bun run test && bun run verify-package && bun run build && bun run verify-package --artifacts","verify-package":"absolute-manifest verify-package"},"_npmUser":{"name":"alexkahndev","email":"alexkahn2019@gmail.com"},"absolutejs":{"runtimePeers":{"react":{"range":">=18.0.0","tested":"19.2.6","optional":true,"buildExternals":["react","react/*"],"artifactImports":["react"]},"elysia":{"range":">=1.0.0","tested":"1.4.29","optional":true,"buildExternals":["elysia","elysia/*"],"artifactImports":["elysia"]}},"manifestContract":2},"repository":{"url":"git+https://github.com/absolutejs/blog.git","type":"git"},"_npmVersion":"10.9.2","description":"Headless, typed blog publishing primitives for AbsoluteJS: post registries, reading metrics, SEO metadata, feeds, sitemap routes, Elysia endpoints, and React hooks without bundled UI.","directories":{},"_nodeVersion":"22.14.0","dependencies":{"@sinclair/typebox":"0.34.52","@absolutejs/manifest":"0.8.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"react":"19.2.6","elysia":"1.4.29","prettier":"3.9.6","@types/bun":"1.3.14","typescript":"6.0.3","@types/react":"19.2.14"},"peerDependencies":{"react":">=18.0.0","elysia":">=1.0.0"},"peerDependenciesMeta":{"react":{"optional":true},"elysia":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/blog_0.1.0_1785506940691_0.9886396245059519","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@absolutejs/blog","version":"0.2.0","description":"Headless, typed blog publishing primitives for AbsoluteJS: post registries, reading metrics, SEO metadata, feeds, sitemap routes, Elysia endpoints, and React hooks without bundled UI.","repository":{"type":"git","url":"git+https://github.com/absolutejs/blog.git"},"homepage":"https://github.com/absolutejs/blog","bugs":{"url":"https://github.com/absolutejs/blog/issues"},"main":"./dist/index.js","module":"./dist/index.js","types":"./dist/index.d.ts","type":"module","license":"BSL-1.1","author":{"name":"Alex Kahn"},"publishConfig":{"access":"public"},"keywords":["absolutejs","blog","content","rss","atom","json-feed","seo","elysia","react"],"scripts":{"build":"rm -rf dist && bun build src/index.ts src/elysia.ts src/react.ts src/manifest.ts --outdir dist --root ./src --sourcemap --target=browser --external react --external 'react/*' --external elysia --external 'elysia/*' --external @absolutejs/manifest --external '@absolutejs/manifest/*' --external @sinclair/typebox --external '@sinclair/typebox/*' && tsc --project tsconfig.build.json && absolute-manifest emit","test":"bun test tests/","typecheck":"tsc --noEmit","format":"prettier --write \"./**/*.{ts,json,md}\"","verify-package":"absolute-manifest verify-package","check:package":"bun run format && bun run typecheck && bun run test && bun run verify-package && bun run build","release":"bun run check:package && npm publish --access public"},"dependencies":{"@absolutejs/manifest":"0.9.0","@sinclair/typebox":"0.34.52"},"peerDependencies":{"elysia":"^2.0.0-beta.6","react":">=18.0.0"},"peerDependenciesMeta":{"elysia":{"optional":true},"react":{"optional":true}},"devDependencies":{"@types/bun":"1.3.14","@types/react":"19.2.14","elysia":"2.0.0-beta.6","exact-mirror":"1.2.4","prettier":"3.9.6","react":"19.2.6","typebox":"1.3.16","typescript":"6.0.3"},"absolutejs":{"manifestContract":2},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./elysia":{"types":"./dist/elysia.d.ts","import":"./dist/elysia.js","default":"./dist/elysia.js"},"./react":{"types":"./dist/react.d.ts","import":"./dist/react.js","default":"./dist/react.js"},"./manifest":{"types":"./dist/manifest.d.ts","import":"./dist/manifest.js","default":"./dist/manifest.js"},"./manifest.json":"./dist/manifest.json","./package.json":"./package.json"},"_id":"@absolutejs/blog@0.2.0","gitHead":"e0651bd0190c27d104bcf3c70f8fcc1007ad6332","_nodeVersion":"22.14.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-Sc81OIZppvjoy8mocJQiOXRdxtyFUEu8AuCHepB3nNspwIihGk1ziUJuR+DuCl71uzAwLPlfpg+odUJvSC7sqw==","shasum":"2c4a2a3425854ecffdb37659a35ccda38718edde","tarball":"https://registry.npmjs.org/@absolutejs/blog/-/blog-0.2.0.tgz","fileCount":22,"unpackedSize":87558,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCEeHeE/C+29haMlzYL8qSdYZgUFQYrs6zucnjw2L3lLgIgciSUEL4Bj1Gdl4svqPDVTTvSv59/7ERmXAAn2DBKN0w="}]},"_npmUser":{"name":"alexkahndev","email":"alexkahn2019@gmail.com"},"directories":{},"maintainers":[{"name":"alexkahndev","email":"alexkahn2019@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/blog_0.2.0_1787188206732_0.7152405106287374"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-31T14:09:00.508Z","modified":"2026-08-20T01:10:07.072Z","0.1.0":"2026-07-31T14:09:00.847Z","0.2.0":"2026-08-20T01:10:06.880Z"},"bugs":{"url":"https://github.com/absolutejs/blog/issues"},"author":{"name":"Alex Kahn"},"license":"BSL-1.1","homepage":"https://github.com/absolutejs/blog","keywords":["absolutejs","blog","content","rss","atom","json-feed","seo","elysia","react"],"repository":{"type":"git","url":"git+https://github.com/absolutejs/blog.git"},"description":"Headless, typed blog publishing primitives for AbsoluteJS: post registries, reading metrics, SEO metadata, feeds, sitemap routes, Elysia endpoints, and React hooks without bundled UI.","maintainers":[{"name":"alexkahndev","email":"alexkahn2019@gmail.com"}],"readme":"# @absolutejs/blog\n\nHeadless blog publishing for AbsoluteJS. The package owns post contracts,\npublication metadata, feeds, sitemap routes, and browser hooks. Your\napplication owns every element and every style.\n\n## Define a blog\n\n```ts\nimport { createBlog, defineAuthor, definePost } from \"@absolutejs/blog\";\n\nconst author = defineAuthor({\n  id: \"alex-kahn\",\n  name: \"Alex Kahn\",\n  role: \"AbsoluteJS\",\n});\n\nconst post = definePost({\n  author,\n  description: \"Why provider differences belong in typed data.\",\n  publishedAt: \"2026-07-31\",\n  slug: \"why-citra-typed-oauth\",\n  tags: [\"OAuth\", \"TypeScript\", \"Citra\"],\n  title: \"Why Citra: Typed OAuth Without Provider Classes\",\n});\n\nexport const blog = createBlog({\n  posts: [post],\n  site: {\n    baseUrl: \"https://absolutejs.com\",\n    description: \"Engineering notes from AbsoluteJS.\",\n    name: \"AbsoluteJS Blog\",\n    publisher: {\n      name: \"AbsoluteJS\",\n      url: \"https://absolutejs.com\",\n    },\n  },\n});\n```\n\n`blog.all()` returns published posts newest first. Drafts stay out of public\nlookups, feeds, and sitemap routes unless explicitly requested.\n\n```ts\nblog.get(\"why-citra-typed-oauth\");\nblog.byTag(\"TypeScript\");\nblog.relatedTo(post);\nblog.sitemapRoutes();\nblog.head(post);\n```\n\n`blog.head(post)` returns canonical, Open Graph, Twitter, article meta, and\n`BlogPosting` JSON-LD values that can be passed to the AbsoluteJS `Head`\ncomponent.\n\n## Feeds\n\nMount all three standard feed formats with the optional Elysia plugin:\n\n```ts\nimport { blogFeeds } from \"@absolutejs/blog/elysia\";\n\nnew Elysia().use(\n  blogFeeds(blog, {\n    rss: \"/blog/rss.xml\",\n    atom: \"/blog/atom.xml\",\n    json: \"/blog/feed.json\",\n  }),\n);\n```\n\nThe literal paths preserve exact Elysia and Eden route inference:\n\n- `/blog/rss.xml`\n- `/blog/atom.xml`\n- `/blog/feed.json`\n\nThe core package also exports `generateRssFeed`, `generateAtomFeed`, and\n`generateJsonFeed` for applications that own their routes.\n\n## Reading hooks\n\nThe React subpath contains hooks, not visual components:\n\n```tsx\nimport {\n  useActiveHeading,\n  useReadingProgress,\n  useReadingTime,\n} from \"@absolutejs/blog/react\";\n\nconst articleRef = useRef<HTMLElement>(null);\nconst progress = useReadingProgress(articleRef);\nconst readingTime = useReadingTime(articleRef);\nconst activeHeading = useActiveHeading(articleRef, sectionIds);\n```\n\nProgress is measured against the article element instead of the entire\ndocument, so a site header and footer do not distort it.\n\n## License\n\nBusiness Source License 1.1. The licensed work converts to Apache 2.0 on\nJuly 31, 2030.\n","readmeFilename":"README.md"}