Browsers get your Craft site as HTML. AI crawlers, APIs, and command-line tools get the same pages as Markdown. Append .md to any entry URL, send Accept: text/markdown, or let GPTBot and ClaudeBot pick it up automatically. A /llms.txt index lists recent entries so tools can discover the Markdown without scraping the HTML.
Marked Down serves the same Craft entry two ways: HTML for browsers, Markdown for everything that asks for it.
The problem
A Craft page is built for humans in a browser - navigation, chrome, scripts, analytics. When ChatGPT, Claude, Perplexity, or curl fetch that URL, they get the whole payload.
The article is in there, buried. Tokens get spent on the layout. Citations get noisier. There is no standard way for a tool to ask Craft for “just the content.”
How a request is served
The same URL, two representations. Markdown is served when any of these is true:
- The URL ends in
.md-/blog/my-article.md - The request sends
Accept: text/markdown - The User-Agent matches a known AI crawler (GPTBot, ClaudeBot, PerplexityBot, and others; the list is configurable)
Everything else gets HTML, untouched. Browsers never see a difference.
curl https://yoursite.com/blog/my-article.md
curl -H "Accept: text/markdown" https://yoursite.com/blog/my-article
Discovery
Tools should not have to guess that Markdown exists.
- HTML pages get a
<link rel="alternate" type="text/markdown">tag pointing at the.mdURL /llms.txtpublishes a site index (llmstxt.org): site name, then each enabled section with recent entries linking to their.mdURLs- Markdown responses send
X-Robots-Tag: noindex, so the.mdversions do not compete with the canonical HTML in search
Per section
Each section can be configured independently. Settings live in project config, keyed by section UID, so they survive renames and sync across environments.
- On or off per section
- AI-bots-only - crawlers get Markdown; a human hitting
.mdor sendingAccept: text/markdownstill gets HTML - Dedicated template - a Twig template that outputs Markdown directly, skipping HTML→Markdown conversion. Receives the
entryvariable - Front matter on or off
Path include/exclude lists still work as a global filter in front of the per-section rules.
What the Markdown looks like
The plugin extracts the main content, strips navigation, headers, footers, and scripts, and converts the rest to Markdown.
Each response can be prefixed with YAML front matter: title, date, updated, author, canonical URL, section. Empty fields are omitted. Front matter is generated fresh on every request, so metadata is never stale.
For sections that already think in Markdown - documentation, changelogs - point the section at a dedicated .md.twig template instead of converting HTML.
CSS selectors in config/marked-down.php can strip extra chrome globally or per template (.sidebar, #comments, and so on).
Also included
- Caching with a configurable TTL; the cache for an entry is cleared when that entry is saved or deleted
- CLI commands to convert a URL, test the converter, clear the cache, and print the current config
- A pluggable front-matter builder if you need extra fields
Requirements
Craft CMS 5.8 or later. PHP 8.2 or later.
To install this plugin, copy the command above to your terminal.
This plugin doesn't have any reviews.