PHPackages                             zeix/craft-marked-down - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Parsing &amp; Serialization](/categories/parsing)
4. /
5. zeix/craft-marked-down

ActiveCraft-plugin[Parsing &amp; Serialization](/categories/parsing)

zeix/craft-marked-down
======================

Marked Down serves Markdown to AI crawlers, command-line tools, and APIs while browsers get HTML. Zero-config per-section setup, automatic AI bot detection, .md URL suffix, /llms.txt, YAML front matter, and dedicated Markdown templates — out of the box.

1.1.0(2w ago)415mitPHPPHP &gt;=8.2

Since Feb 4Pushed 2w agoCompare

[ Source](https://github.com/zeixcom/craft-marked-down)[ Packagist](https://packagist.org/packages/zeix/craft-marked-down)[ RSS](/packages/zeix-craft-marked-down/feed)WikiDiscussions main Synced today

READMEChangelog (3)Dependencies (8)Versions (4)Used By (0)

Marked Down
===========

[](#marked-down)

A Craft CMS plugin that intelligently serves Markdown content to AI tools, APIs, and command-line clients, while browsers continue to receive HTML.

Why Marked Down?
----------------

[](#why-marked-down)

### The Problem

[](#the-problem)

Modern websites are designed for humans viewing them in browsers—complete with navigation menus, sidebars, footers, analytics scripts, and styling. But when AI tools like ChatGPT, Claude scrape your site, they get the entire HTML payload.

Result: **Wasted tokens, confused AI models, cluttered API responses, and poor developer experience.**

### The Solution

[](#the-solution)

Marked Down uses HTTP content negotiation to serve clean, semantic Markdown when appropriate:

**Benefits:**

- 🎯 **10-15x smaller responses** - Markdown is dramatically more compact than HTML
- 🤖 **Better AI understanding** - LLMs process clean Markdown more effectively than noisy HTML
- 🔌 **Standard HTTP** - Uses the `Accept: text/markdown` header (proper content negotiation)
- 🌐 **Zero impact on browsers** - Your website looks and works exactly the same for human visitors
- ⚡ **Built-in caching** - Fast responses with configurable cache duration
- 🎨 **Smart extraction** - Automatically finds and converts your main content, stripping navigation and boilerplate

### Real-World Use Cases

[](#real-world-use-cases)

- **Documentation sites** - Let AI assistants cite your docs accurately
- **Technical blogs** - Make your content easily consumable by AI tools
- **API documentation** - Serve both human-readable HTML and machine-readable Markdown
- **Content APIs** - Provide Markdown output without building separate endpoints
- **AI training** - Offer clean content for AI model training datasets
- **Command-line tools** - Enable CLI users to read your content in their terminal

Installation
------------

[](#installation)

### Standard Installation

[](#standard-installation)

```
composer require zeix/craft-marked-down
./craft plugin/install marked-down
```

### DDEV Installation

[](#ddev-installation)

If you're using DDEV for local development:

```
ddev composer require zeix/craft-marked-down
ddev craft plugin/install marked-down
```

How It Works
------------

[](#how-it-works)

Marked Down serves the same entry as Markdown when a client asks for it, and as normal HTML otherwise. A request is served Markdown when **any** of these is true:

1. **`.md` URL suffix** — append `.md` to any entry URL (e.g. `/blog/my-article.md`).
2. **`Accept: text/markdown`** header — standard HTTP content negotiation.
3. **AI bot User-Agent** — the request comes from a known crawler (GPTBot, ClaudeBot, PerplexityBot, and others; configurable).

Everything else gets HTML, untouched. On HTML pages the plugin also injects a `` tag so Markdown-aware clients can discover the `.md` version, and Markdown responses carry `X-Robots-Tag: noindex` so they don't compete with your canonical HTML in search.

### Quick Test

[](#quick-test)

```
# .md suffix
curl https://yoursite.com/blog/my-article.md

# Accept header
curl -H "Accept: text/markdown" https://yoursite.com/blog/my-article

# As an AI bot
curl -A "GPTBot/1.0" https://yoursite.com/blog/my-article

# Normal browser request — unchanged HTML
curl https://yoursite.com/blog/my-article
```

Each Markdown response is prefixed with YAML front matter (title, date, author, canonical URL, section) and has navigation, headers, footers, and scripts stripped out.

Configuration
-------------

[](#configuration)

### Plugin Settings

[](#plugin-settings)

Navigate to **Settings → Plugins → Marked Down**:

- **Enable Marked Down**: Toggle the plugin on/off
- **Excluded Paths**: Paths that always serve HTML (e.g., `/admin`, `/actions/*`)
- **Include Only Paths**: (Optional) Restrict Markdown to specific paths. Leave empty to allow all paths — if set, **only** matching paths serve Markdown.
- **AI Bot User-Agents**: The crawler patterns that trigger Markdown (matched case-insensitively against the User-Agent).
- **Caching**: Enable caching and set cache duration (default: 24 hours)

### Per-section settings

[](#per-section-settings)

Each section can be configured independently (stored in project config, keyed by section UID so it survives renames and syncs across environments):

- **Enabled**: Serve Markdown for this section at all (default: on).
- **AI-bots-only**: Serve Markdown *only* to detected AI bots. Humans hitting the `.md` URL or sending `Accept: text/markdown` still get HTML — useful when you want crawlers fed but the `.md` URLs kept out of public reach.
- **Dedicated template**: Point a section at a Twig template that outputs raw Markdown directly, bypassing HTML→Markdown conversion entirely. Receives the `entry` variable.
- **Front matter**: Toggle the YAML front-matter block per section.

### llms.txt

[](#llmstxt)

Marked Down publishes a `/llms.txt` site index following the [llms.txt spec](https://llmstxt.org/) — a per-section list of recent entries linking to their `.md` URLs, so AI tools can discover your Markdown content from one file. Configure the number of entries per section in the plugin settings (`llmsTxtEntriesPerSection`, default 20).

### Config File

[](#config-file)

Create `config/marked-down.php` to exclude specific CSS selectors from Markdown output:

```
