Section and sitemap routes for agent-friendly docs
Section and Sitemap Routes
Individual articles are useful, but agents often want the full picture.
- Create a dedicated
/sitemap.mdroute for content discovery - Understand the two-tier content strategy
- Optimize queries for navigation vs full content
When an AI agent first encounters your documentation, it needs to discover what's available. The sitemap is the entry point — a structured list of all sections and articles.
/sitemap.mdThis is different from an XML sitemap for SEO. It's a human-readable (and agent-readable) markdown document that shows the content structure.
Create the route directory:
mkdir -p src/app/sitemap.mdCreate the Route Handler:
import { client } from '@/sanity/client'import { SITEMAP_QUERY } from '@/sanity/queries'import { buildSitemapMarkdown } from '@/lib/markdownSerializers'
/** * Sitemap route at /sitemap.md * Provides a markdown-formatted index of all documentation. */export async function GET() { try { const sections = await client.fetch(SITEMAP_QUERY) const markdown = buildSitemapMarkdown(sections)
return new Response(markdown, { headers: { 'Content-Type': 'text/markdown; charset=utf-8', 'Cache-Control': 'public, max-age=300, stale-while-revalidate=600', }, }) } catch (error) { console.error('Sitemap route error:', error) return new Response('Internal server error', { status: 500 }) }}The generated sitemap looks like:
# Keplar Docs Sitemap
## How to Access Content as Markdown
- **Any page**: Add `.md` to the URL or use `Accept: text/markdown` header- **Section listing**: `/docs/[section].md`- **This sitemap**: `/sitemap.md`
---
## Getting Started
Get up and running with Keplar in minutes.
- [Quickstart](/docs/getting-started/quickstart) — Create your first API call- [Installation](/docs/getting-started/installation) — Install the SDK- [Authentication](/docs/getting-started/authentication) — Set up API keys
## API Reference
Complete API documentation.
- [Endpoints](/docs/api-reference/endpoints) — Available endpoints- [Error Codes](/docs/api-reference/errors) — Error handlingThis gives agents:
- Instructions for accessing markdown
- Full structure of all sections and articles
- Summaries to understand what each article covers
We use different query strategies for different purposes:
Section listings and the sitemap don't include article content — just titles, slugs, and summaries:
// SECTION_QUERY - no content field{ title, slug, description, "articles": *[...] { title, slug, summary // No content! }}This keeps responses small. A section with 20 articles would be overwhelming if every article included full content.
Article routes include the full content:
// ARTICLE_QUERY - includes content{ title, slug, summary, content, // Full Portable Text "section": section-> { ... }}This is appropriate for single-article requests where the agent wants the complete content.
The folder is literally named sitemap.md:
src/app/sitemap.md/└── route.tsThis creates a route at /sitemap.md. The .md is part of the path, not a file extension. Next.js handles this correctly.
If you already have a sitemap.ts for XML sitemaps, they won't conflict. /sitemap.xml and /sitemap.md are different routes.
Section routes use the .md suffix pattern, just like articles:
/docs/getting-started.md → Section listing (markdown)/docs/getting-started → Section page (HTML)We created a dedicated Route Handler at /md/[section]/route.ts and configured rewrites to handle .md suffix requests.
Test the sitemap:
curl http://localhost:3000/sitemap.mdExpected output:
# Keplar Docs Sitemap
## How to Access Content as Markdown
- **Any page**: Add `.md` to the URL or use `Accept: text/markdown` header- **Section listing**: `/docs/[section].md`- **This sitemap**: `/sitemap.md`
---
## Getting Started...Test a section listing with the .md suffix:
curl http://localhost:3000/docs/getting-started.mdOr using the Accept header:
curl -H "Accept: text/markdown" http://localhost:3000/docs/getting-startedExpected output:
# Getting Started
Get up and running with Keplar in minutes.
## Articles
- [Quickstart](/docs/getting-started/quickstart) Create your first API call in under 5 minutes- [Installation](/docs/getting-started/installation) Install the SDK for your platformDifferent routes get different cache durations:
- Sitemap — 5 min cache (structure changes rarely)
- Section — 5 min cache (article list changes rarely)
- Article — 1 min cache (content may update frequently)
// Sitemap - longer cache'Cache-Control': 'public, max-age=300, stale-while-revalidate=600'
// Article - shorter cache'Cache-Control': 'public, max-age=60, stale-while-revalidate=300'/sitemap.mdreturns the full sitemap/docs/[section].mdreturns a section listing (articles only, no content)- Accept header also works for sections:
Accept: text/markdown - Sitemap includes instructions for accessing markdown
- Cache headers are appropriate for each route type