Nex Boosts Next.js with Content Negotiation, Serving Markdown to LLMs and HTML to Browsers
Photo by Possessed Photography on Unsplash
A single URL can now deliver HTML to browsers and Markdown to AI agents, thanks to a new Next.js plugin that leverages the HTTP Accept header, eliminating duplicate endpoints and stale content.
Key Facts
- •Key company: Nex
The plugin, dubbed next‑md‑negotiate, plugs a missing piece into Next.js by turning the HTTP Accept header into a content‑type router, something the framework has never offered out of the box. According to the GitHub repository for the project, the tool intercepts requests that ask for `text/markdown` (or its aliases) and silently rewrites them to an internal API route that returns a Markdown string you define, while ordinary browser requests continue to receive the standard HTML page. The result is a single URL that can serve both human‑readable HTML and machine‑readable Markdown without the need for duplicate endpoints such as `/api/products/123.md` — a pain point the repo’s README explicitly calls out as “duplicates your routing, goes stale, and clients have to know about a non‑standard URL scheme.”
Implementation is deliberately minimal. Developers add a catch‑all route under `app/md-api/[...path]/route.ts` (or the Pages Router equivalent) that imports `createMdHandler` from the package and wires it to a configuration file (`md.config.ts`). That config lists type‑safe “Markdown versions” using `createMdVersion`, pairing a URL pattern with an async function that fetches data and returns a Markdown string. Examples in the repo show a product page (`/products/[productId]`) that pulls a record from a `db.products` collection and formats it as a heading, price line, and description, and a blog post (`/blog/[slug]`) that renders the post title and body. Because the parameters are inferred from the route pattern, developers get compile‑time safety without extra boilerplate.
The rewrite logic lives in `next.config.js`. A helper called `createRewritesFromConfig` reads the same `mdConfig` array and generates Next.js rewrites that fire before the file system routing stage. If the incoming request’s Accept header matches one of the Markdown MIME types, the rewrite sends the request to the internal `/md-api/...` handler; otherwise the request proceeds to the normal page rendering pipeline. The README notes that this approach works with any supported Next.js version and with both the App Router and the legacy Pages Router, meaning teams can adopt it without a full migration.
Beyond the technical convenience, the plugin addresses a growing demand from AI agents that scrape the web for structured content. The repo’s description points out that “LLMs, crawlers, and AI agents want Markdown,” and that the Accept header already provides a standards‑based way to signal that preference. By exposing Markdown at the same endpoint that browsers use for HTML, developers can keep content fresh—there’s no need to maintain a parallel static `.md` file that could fall out of sync. In practice, an LLM client would issue `GET /products/42` with `Accept: text/markdown` and receive a clean, parsable Markdown payload, while a human visitor’s browser still receives the full React‑driven page.
Early adopters can spin up the tool with a single `npm install next-md-negotiate` or by running `npx next-md-negotiate init`, which scaffolds the necessary files. The GitHub README emphasizes that the solution is “no new URLs, no duplicate routing,” positioning it as a low‑friction upgrade for existing Next.js codebases that need to serve both HTML and Markdown. While the plugin is still a community project rather than an official Next.js feature, its straightforward API and reliance on standard HTTP semantics make it a compelling bridge between web front‑ends and the emerging ecosystem of AI‑driven content consumers.
Sources
This article was created using AI technology and reviewed by the SectorHQ editorial team for accuracy and quality.