# Markdown Alternates Guide — serving .md alongside .html for AI engines

**Canonical:** https://www.eastbound.ai/markdown-alternates-guide/
**Updated:** 2026-05-07

Per-page Markdown alternates let AI engines fetch your content as clean Markdown instead of HTML. The signal is small in absolute terms but compounds: cleaner extraction, fewer parsing errors, less navigation noise carried into citations.

## Why a Markdown alternate, not just clean HTML

Modern HTML pages carry structural overhead: header navigation, sidebar links, related-article carousels, marketing CTAs, footer columns, GDPR banners, structured-data scripts, analytics tags. When an AI engine fetches the page, it has to identify and discard all of that before reaching the body text. A Markdown alternate is the same content rendered to clean Markdown — body copy, headings, lists, code blocks, internal links — without the chrome.

**What this is not.** Markdown alternates are not a ranking signal. Google does not boost pages with Markdown alternates. The benefit is downstream: when an engine cites your page, the citation is grounded in cleaner text. Treat this as *extraction quality*, not *retrieval boost*.

## How to declare the alternate

In the HTML page's `<head>`:

```
<link rel="alternate" type="text/markdown" href="/foo/index.md" />
```

Three things matter:

- **The `type` attribute is `text/markdown`**, not `text/plain`.
- **The `href` is path-based, not extension-based on the page URL.** A page at `/foo/` declares `/foo/index.md`. A page at `/foo.html` declares `/foo.md`.
- **One per page.** Don't declare multiple Markdown alternates with different language or content variants.

Mirror the declaration in `llms.txt` under "Markdown alternates". See [/llms-txt-vs-robots-txt/](https://www.eastbound.ai/llms-txt-vs-robots-txt/) for the format.

## What to put in the .md file

The Markdown file is a clean, content-only rendering. Strip:

- Site header, navigation, breadcrumbs
- CTAs, banners, modal triggers, GDPR consent
- Sidebar promotional content, related-article carousels
- Footer link columns, social links, copyright
- Inline tracking, analytics scripts, ad slots

Keep:

- The page title as H1
- A short canonical/updated metadata block at the top
- Body headings and paragraphs as Markdown
- Lists, tables, code blocks, blockquotes
- Internal links (full URLs, not relative)
- External citations as proper Markdown links

The Markdown file should be content-equivalent, not a stripped-down summary. Truncating defeats the purpose: short alternates produce short citations.

## Stack patterns

### Static site (Hugo, Jekyll, 11ty, Astro, Next.js SSG)

The natural fit. Source content from Markdown files; render the *same* source to both `index.html` and `index.md` in the output directory. Hugo's [output formats](https://gohugo.io/templates/output-formats/) support this directly. Astro and 11ty support similar through plugins or build hooks.

### CMS-backed (WordPress, Contentful, Sanity, Strapi)

The source-of-truth is structured data, not Markdown. Two patterns:

- **Render Markdown server-side**: add a `/foo/index.md` route that serializes the same content with Turndown or a custom block-renderer, returning `Content-Type: text/markdown`.
- **Build-time export**: a nightly job iterates all CMS entries and writes static `.md` files served by your CDN.

Build-time is simpler; render-time stays fresh.

### Edge-function dynamic (Cloudflare Workers, Vercel Edge, Lambda@Edge)

An edge function intercepts `*.md` requests, fetches upstream HTML, runs it through `turndown` / `html-to-md` / `node-html-markdown` with rules tuned to strip your specific chrome, and returns the result with the right content type. Cache aggressively — once per content edit, not per request.

**Authoring once, rendering twice.** The cleanest pattern: keep source-of-truth content in Markdown, render Markdown directly to `.md`, render Markdown through your template engine to `.html`. The two outputs share a source and cannot drift.

## Content-Type and HTTP details

The HTTP response must declare `Content-Type: text/markdown` (or `text/markdown; charset=utf-8`). Several engines refuse a `.md` file served as `application/octet-stream` or `text/plain`.

**S3:** `aws s3 cp ... --content-type "text/markdown; charset=utf-8"` explicitly for every `.md` file.

**Netlify** (`_headers`):
```
/*.md
  Content-Type: text/markdown; charset=utf-8
```

**Vercel** (`vercel.json`):
```json
{
  "headers": [
    {
      "source": "/(.*)\\.md",
      "headers": [
        { "key": "Content-Type", "value": "text/markdown; charset=utf-8" }
      ]
    }
  ]
}
```

**nginx / Apache:** MIME-type mapping in server config.

Verify with `curl -I https://www.example.com/foo/index.md`.

## Per-page alternates vs a single llms-full.txt bundle

Per-page alternates let an engine fetch the specific page it's citing — small payload, URL-matched. A bundled `llms-full.txt` lets an engine ingest the whole site in one fetch, suiting engines that context-load before answering.

**Recommendation:** ship per-page alternates as baseline. Add `llms-full.txt` as a supplement when the site has fewer than ~50 pages and total Markdown fits in a few hundred kilobytes. Don't ship `llms-full.txt` for sites with thousands of pages.

## Shipping checklist

1. Decide your source-of-truth pattern.
2. Generate `.md` at the canonical path of every shipping page.
3. Verify content-equivalence with HTML rendering, chrome stripped.
4. Set `Content-Type: text/markdown; charset=utf-8` on deploy.
5. Add `<link rel="alternate" type="text/markdown" href="..." />` to HTML head.
6. List the alternate in `/llms.txt` under "Markdown alternates".
7. Smoke-test: `curl -sI` for content type, `curl -s` for body.
8. Re-test after every content change — drift is the main failure mode.

## Related reading

- [AI crawler readiness — the infrastructure layer](https://www.eastbound.ai/ai-crawler-readiness/)
- [llms.txt vs robots.txt](https://www.eastbound.ai/llms-txt-vs-robots-txt/)
- [AI crawler blocking mistakes](https://www.eastbound.ai/ai-crawler-blocking-mistakes/)
- [IndexNow setup guide](https://www.eastbound.ai/indexnow-setup-guide/)
- [China AI visibility pillar](https://www.eastbound.ai/china-ai-visibility/)
