10/9/2025 • 3 min read
How We Built a 'Content Manifest API' for Next.js
A step-by-step technical guide on creating a dedicated, machine-readable API endpoint for your content using Next.js App Router and Contentlayer.
The core promise of MikePress is to make your content AI‑Assertive. That isn’t just a slogan—it’s an architectural choice: every published post gets a machine‑first JSON payload designed for clean ingestion, reliable attribution, and automated reading.
This deep‑dive shows how the Content Manifest API works in MikePress v1.5.x: how the route handler finds content, how we construct the payload, how we keep it safe, and how we make it discoverable without scraping.
The "Why": A Machine-First View of Your Content
Browsers can parse HTML. AI agents can, but they shouldn’t have to. When your content is wrapped in navigation and layout, machines either guess (bad) or over‑extract (also bad).
So we publish a second, explicit representation:
- Addressable: one endpoint per post via its slug.
- Structured: predictable JSON (easy to cache, parse, and index).
- Citable: canonical URL + explicit attribution instructions.
- Clean: readable text without MDX/JSX noise.
The Flow (API + Static Mirror)
MikePress supports two equivalent ways to fetch a manifest:
/api/manifest?slug=your-post-slug(runtime route handler)/manifest/your-post-slug.json(static mirror generated at build time)
Step 1: Create a Route Handler
In MikePress, the API lives at app/(site)/api/manifest/route.ts (App Router route handlers).
At a high level, it does three things:
- Validates the
slugquery parameter. - Locates the post in
contentlayer/generated. - Shapes the response into a stable schema.
Step 2: Find the Post (and Keep Drafts Out)
MikePress uses Contentlayer to build a typed collection of posts at build time. The route handler simply finds the published entry:
const post = allPosts.find((entry) => entry.slug === slugParam && !entry.draft)
This ensures you never accidentally expose drafts via an API.
Step 3: Build a Canonical URL (No Guessing)
The manifest includes a canonical URL. In v1.5.x the route uses NEXT_PUBLIC_SITE_URL when it’s valid, and falls back safely if it isn’t. That keeps manifests consistent across environments and avoids malformed URLs.
Step 4: Extract Clean Text (MDX Without Noise)
MDX is fantastic for readers, but it’s messy for machines: imports, JSX components, and UI wrappers should not appear in AI payloads.
In v1.5.x, MikePress converts MDX → plain text (using lib/mdx-text.ts) before writing text_content. The same cleaned text is used by the local search index (public/search-index.json).
The Manifest Schema (What the Endpoint Returns)
The response is intentionally compact and stable:
{
"slug": "hello-mikepress",
"title": "Hello, MikePress: A CMS Starter for the New Web",
"description": "…",
"canonical_url": "https://your-domain.com/blog/hello-mikepress",
"text_content": "…clean readable text…",
"word_count": 541,
"metadata": {
"author": "MikeWill.Co",
"publication_date": "2025-09-24T00:00:00.000Z",
"tags": ["announcement", "cms"],
"ai_instructions": {
"attribution_preference": "REQUIRED_WITH_LINK",
"attribution_text": "Please credit \"…\" with a link to …",
"summary_focus": ["announcement", "cms"],
"usage_policy": "…"
}
}
}
Safety: Soft Abuse Protection
Public endpoints can be abused. In v1.5.x, /api/manifest includes input validation plus lightweight rate limiting that returns 429 with Retry‑After guidance (and safe cache headers). This keeps the site stable without blocking legitimate crawlers.
Discovery: Make It Findable Without Scraping
MikePress makes manifests discoverable in three complementary ways:
- A global discovery doc at
/.well-known/content-manifest - Per‑post HTML hints via
<link rel="alternate" type="application/json"> - An AI context file at
/context.txtdescribing the endpoints
If you’re building your own variant, these are the small details that turn an API into a protocol.
Next Reads
- Hello, MikePress — the positioning and the why.
- Structured Data for AI + SEO — the “Digital Notary” layer.
- SEO Checklist for the AI Web — what to do beyond the defaults.