Core Concepts

Markdown Conversion

Last updated by Harlan Wilton in fix!: rework module.

mdream converts HTML pages to markdown during prerendering and runtime.

Build-Time

During nuxi generate:

  1. Nuxt plugin queues .md route for each rendered page (/about//about/index.md)
  2. Prerender middleware fetches HTML, converts to markdown, extracts metadata
  3. ai-ready:page:markdown hook fires per page
  4. Content appended to page-data.jsonl and streamed to llms-full.txt
  5. Route serves raw markdown

Metadata extracted: title, description, headings, updatedAt (from article:modified_time etc).

Runtime

Markdown served when:

  • Path ends in .md (explicit), OR
  • Accept includes text/markdown AND NOT text/html AND sec-fetch-destdocument

Targets API clients (Claude Code, curl, Bun) while excluding browsers.

curl https://example.com/about.md
curl -H "Accept: text/markdown" https://example.com/about

Configuration

nuxt.config.ts
export default defineNuxtConfig({
  aiReady: {
    mdreamOptions: {
      preset: 'minimal',
    },
    markdownCacheHeaders: {
      maxAge: 3600,
      swr: true,
    },
  },
})

Hooks

'ai-ready:mdreamConfig'

Modify mdream options before conversion:

server/plugins/mdream-config.ts
export default defineNitroPlugin((nitroApp) => {
  nitroApp.hooks.hook('ai-ready:mdreamConfig', (options) => {
    if (options.origin?.includes('/blog/'))
      options.ignoreElements = [...(options.ignoreElements || []), '.author-bio']
  })
})

'ai-ready:markdown'

Modify markdown output at runtime:

server/plugins/markdown-footer.ts
export default defineNitroPlugin((nitroApp) => {
  nitroApp.hooks.hook('ai-ready:markdown', (ctx) => {
    ctx.markdown = `---\ntitle: ${ctx.title}\n---\n\n${ctx.markdown}`
  })
})

See Nitro Hooks for context types.

Did this page help you?