agentblog.dev/docs

What gets installed

A file-by-file tour of the 71 files AgentBlog writes into your repository, and the rules each piece obeys.

Everything below lands in your repository as source you own and can edit. The paths assume a flat layout. In a src/ layout, shadcn resolves them against your components.json aliases.

Routes

FileWhat it does
app/blog/layout.tsxImports the preflight check, adds the editorial policy link
app/blog/page.tsxPaginated index with Blog structured data
app/blog/[slug]/page.tsxThe post route
app/blog/[slug]/opengraph-image.tsxThe social card for each post
app/blog/category/[slug]/page.tsxCategory hub, always indexable
app/blog/tag/[slug]/page.tsxTag listing, noindex below your configured post count
app/authors/[slug]/page.tsxAuthor page emitting Person structured data
app/editorial-policy/page.tsxOptional, ships as @agentblog/eeat-pages

Five rules are baked into these files, and each one closes a failure that has no visible symptom.

generateStaticParams returns every slug. Never sliced, never paginated. Every post becomes complete static HTML at build time, which is the safest possible shape for a crawler that fetches once and runs no JavaScript.

No 'use client' in the article render path. Two components are allowed to be client components, the table of contents for its scroll tracking and the share buttons, and both render their full content on the server first. The FAQ and the table of contents use <details> and CSS rather than mounting on interaction, so their text is in the HTML whether or not anything hydrates.

One <h1> per page, a <time> element on every date, a stable id on every H2 and H3, and rel="author" on the byline link.

Every route that sets openGraph or robots spreads the shared defaults from lib/metadata.ts. See the shallow merge trap.

Pagination renders real links. A paginator that only works after hydration hides everything past page one from a crawler.

SEO routes

FileNotes
app/sitemap.tslastModified comes from each post's dateModified, never from the build time
app/robots.tsGuarded on the deployment environment, and emits your aiAccess rules
app/feed.xml/route.tsRSS 2.0
app/opengraph-image.tsxThe site-level social card
app/not-found.tsxA 404 that links back into the content rather than being a dead end
app/api/publish/route.tsRevalidation and IndexNow, in that order

sitemap.xml, robots.txt, feed.xml, and the social images are all cached route handlers. That is why the publish webhook revalidates the sitemap and the feed explicitly rather than only the post paths: a new post that never reaches either is a failure with no symptom.

Components

components/blog/ holds the reading experience: the answer capsule, the author bio, breadcrumbs, the byline, category pills, icons, the structured data serialiser, pagination, the post card, the post list, the prose wrapper, related posts, share buttons, and the table of contents.

components/mdx/ holds the component map plus the callout, code block, FAQ, figure, key takeaways, quote, stat, and table. See components you can use in a post.

components/blog/icons.tsx re-exports every icon used anywhere in the block, so swapping icon libraries costs one file rather than a search across twelve components.

components/blog/type-scale.ts is the design system, and it is the file to open first if you want the blog to look like the rest of your product. It holds the heading, lede, section, eyebrow, and meta roles as class strings, plus the two gaps every page composes with. Editing one constant there restyles every route at once, which is the reason the routes import from it instead of spelling out their own headings. The layout widths it composes against live in styles/agentblog.css as --agentblog-measure, --agentblog-aside, --agentblog-article, and --agentblog-rail.

One rule in that file is worth repeating here, because breaking it is how the spacing goes wrong: no component sets its own outer margin. Pages stack their children in a flex column with a gap, so a component that is missing from the layout is a component that is visibly missing, rather than one that silently renders flush against its neighbour.

Library

FileResponsibility
lib/config.tsThe resolved config and the URL helpers. The only file that reads your config
lib/posts.tsThe content source facade. Every route reads posts through this file
lib/schema.tsThe structured data builders, typed rather than hand-written JSON
lib/metadata.tsThe shared metadata defaults every route spreads
lib/render-mdx.tsxThe only place MDX is compiled
lib/mdx-plugins/Table of contents extraction and answer capsule handling
lib/toc.ts, lib/reading-time.tsHeading extraction, word count and minutes
lib/indexnow.tsSubmission, with the response codes surfaced rather than swallowed
lib/ai-referrers.tsClassifies assistant referrals. See measuring
lib/sources/mdx.tsThe MDX content source

Four files are generated and carry a banner saying so: lib/schemas.ts, lib/types.ts, lib/define-config.ts, and lib/preflight-checks.ts. They are generated rather than imported because they ship into your repository, where there is no package of ours to import from. Do not edit them: they are the files most likely to carry a real fix in an update, and they are always safe to overwrite.

The shallow merge trap

Worth stating on its own, because it is invisible to the type checker and it is the single most common way a correct-looking blog loses metadata.

Next.js merges metadata across segments shallowly. If your root layout sets:

openGraph: { siteName: 'Your Brand', locale: 'en_US', type: 'website' }

and a post page sets:

openGraph: {
  type: 'article',
  title: post.title,
  description: post.description,
  url: canonical,
  images: [ogImage],
}

then because the page defined openGraph at all, the layout's entire object is discarded. Every post ships a social card with no site name and no locale. Nothing errors, no validator complains, and the types are correct. The only way to notice is to view source on a built page.

lib/metadata.ts exists so that no route file can make this mistake by accident, and agentblog doctor asserts it against built HTML rather than against the source.

Styles

styles/agentblog.css carries two things: the bridge from the typography plugin to your theme tokens, and the --agentblog- prefixed variables for the reading measure and the prose scale. See make it look like your site.

Nothing imports this file for you. That is the one install step with no warning attached.

Content

content/blog/*.mdx, content/authors.json, and content/categories.json.

Two example posts ship with the block, licensed CC0, because they become your published content and an attribution requirement would mean every AgentBlog user owed credit on their own blog.

They are also the format specification. They are what the write-blog-post skill patterns from, so they follow every rule in the GEO playbook, including the copy style rules. Read one before you delete them.

On this page