> **Can't find what you're looking for?** Use `search_docs` on the docs MCP server at `https://vocs.dev/api/mcp` to find what you need.
>
> **Have feedback?** Use `submit_feedback` on the same MCP server.

# Rehype & Remark \[Customize the Markdown and HTML pipeline]

## Overview

Vocs compiles Markdown and MDX through the unified ecosystem. Add remark plugins when you want to transform Markdown before it becomes HTML. Add rehype plugins when you want to transform HTML before it is rendered. Add recma plugins only when you need to transform the JavaScript module produced by MDX.

Configure all three through the `markdown` option in `vocs.config.ts` — you only need `vite.config.ts` when you are changing Vite itself.

:::note
Vocs already includes plugins for callouts, code groups, frontmatter, Mermaid, snippets, file trees, steps, syntax highlighting, heading anchors, and image sizing. Add custom plugins when your project needs behavior outside the built-in [Markdown Extensions](/writing/markdown-extensions).
:::

## Setup

::::steps
### Install A Plugin

Install the remark or rehype plugin you want to use.

:::code-group
```bash [npm]
npm install rehype-external-links
```

```bash [pnpm]
pnpm add rehype-external-links
```

```bash [yarn]
yarn add rehype-external-links
```

```bash [bun]
bun add rehype-external-links
```
:::

### Run Dev Server

Start the development server and open a page that uses the affected Markdown.

:::code-group
```bash [npm]
npm run dev
```

```bash [pnpm]
pnpm dev
```

```bash [yarn]
yarn dev
```

```bash [bun]
bun run dev
```
:::
::::

## Recipes

### Add Remark Plugins

Use `remarkPlugins` for transforms that work on Markdown syntax, such as adding custom directives, rewriting headings, or changing code block metadata before HTML is generated.

```ts [vocs.config.ts]
import remarkGemoji from 'remark-gemoji'
import { defineConfig } from 'vocs/config'

export default defineConfig({
  markdown: {
    remarkPlugins: [remarkGemoji] // [!code focus]
  }
})
```

### Change Generated Markdown Only

Use `outputRemarkPlugins` when an authored page needs a simpler Markdown form than its interactive form. These plugins run for authored page bodies used in per-page `.md` files and `llms-full.txt`, but do not change the rendered site.

This is useful for replacing custom MDX components with plain headings, links, prose, or code. It uses the normal remark plugin format, so a plugin can read component names, props, and children without a separate Vocs component registry.

```js [remark-plain-components.mjs]
export default function unwrapPageGrid() {
  return (tree) => {
    for (let index = tree.children.length - 1; index >= 0; index--) {
      const node = tree.children[index]
      if (node.type !== 'mdxJsxFlowElement' || node.name !== 'PageGrid') continue
      tree.children.splice(index, 1, ...node.children)
    }
  }
}
```

```ts [vocs.config.ts]
import { defineConfig } from 'vocs/config'
import unwrapPageGrid from './remark-plain-components.mjs'

export default defineConfig({
  markdown: {
    outputRemarkPlugins: [unwrapPageGrid] // [!code focus]
  }
})
```

Components that the plugin does not replace stay as MDX in the generated Markdown.

### Add Rehype Plugins

Use `rehypePlugins` for transforms that work on HTML, such as adding attributes to links, rewriting elements, or integrating HTML-focused plugins.

```ts [vocs.config.ts]
import rehypeExternalLinks from 'rehype-external-links'
import { defineConfig } from 'vocs/config'

export default defineConfig({
  markdown: {
    rehypePlugins: [ // [!code focus:8]
      [
        rehypeExternalLinks,
        {
          rel: ['noopener', 'noreferrer'],
          target: '_blank'
        }
      ]
    ]
  }
})
```

### Add Recma Plugins

Use `recmaPlugins` only when you need to transform the JavaScript module produced by MDX. Most projects should prefer remark or rehype plugins — recma plugins operate later in the pipeline and are easier to make dependent on MDX internals.

```ts [vocs.config.ts]
import recmaExportFilepath from 'recma-export-filepath'
import { defineConfig } from 'vocs/config'

export default defineConfig({
  markdown: {
    recmaPlugins: [recmaExportFilepath] // [!code focus]
  }
})
```

## Plugin Order

Vocs runs its built-in Markdown plugins first, followed by `remarkPlugins`. When Vocs generates Markdown, `outputRemarkPlugins` run last. Custom rehype plugins run after syntax highlighting and heading anchors, then Vocs finishes link and image processing.

## Reference

<Cards>
  <Card title="markdown config" description="remarkPlugins, rehypePlugins, recmaPlugins, and remarkRehypeOptions." icon="settings" to="/reference/site-config#markdown" />

  <Card title="Markdown Extensions" description="Built-in callouts, code groups, file trees, steps, snippets, and more." icon="book-open" to="/writing/markdown-extensions" />

  <Card title="Vite" description="Extend the underlying Vite stack with custom plugins." icon="zap" to="/features/vite" />
</Cards>
