---
title: MarkdownEditor
description: A Markdown editor with WYSIWYG, source, and preview modes.
category: Advanced
status: beta
since: 0.3.9
tags: [markdown, editor, wysiwyg]
syncStatus: reviewed
verified: true
---

## Usage

### Basic
`defaultMode` sets the starting mode; `toolbarActions` picks the toolbar buttons and their order.
::::TuffDemoWrapper{demo="MarkdownEditorMarkdownEditorDemo" code-lang="vue"}
---
code: |
  <script setup lang="ts">
  import { ref } from 'vue'

  const content = ref('## Release note\n\n- API reviewed\n- Demos verified')
  </script>

  <template>
    <TxMarkdownEditor
      v-model="content"
      default-mode="source"
      :toolbar-actions="['heading', 'bold', 'italic', 'bulletList', 'orderedList', 'link']"
    />
  </template>
---
::::

### Best Practices

- Keep `sanitize=true` for content written by users or providers.
- Use a controlled `mode` when the route or query stores it.
- Restrict `toolbarActions` in narrow editors such as release notes or comments.
- Collect URLs with your own dialog through `linkPrompt`; don't make the component own product dialogs.
- If the host doesn't scan tuffex sources, add `MARKDOWN_EDITOR_ICON_CLASSES` from `src/toolbar-icons.ts` to the UnoCSS safelist.

## API Reference

### Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `modelValue` / `v-model` | `string` | `''` | The Markdown source. |
| `placeholder` | `string` | `''` | Placeholder in the editable modes. |
| `mode` | `'wysiwyg' \| 'source' \| 'preview'` | - | Controlled mode. |
| `defaultMode` | `'wysiwyg' \| 'source' \| 'preview'` | `'wysiwyg'` | Starting mode when uncontrolled. |
| `disabled` | `boolean` | `false` | Disables the toolbar, mode switcher, and editing surface. |
| `readonly` | `boolean` | `false` | Blocks editing; reading and mode switching still work. |
| `sanitize` | `boolean` | `true` | Sanitizes rendered HTML with DOMPurify; turn off only for trusted content. |
| `theme` | `'auto' \| 'light' \| 'dark'` | `'auto'` | Theme; `auto` follows the page. |
| `toolbar` | `boolean` | `true` | Shows the toolbar and mode switcher. |
| `toolbarActions` | `MarkdownEditorToolbarActionKey[]` | built-in set | Toolbar buttons, in order. |
| `minHeight` | `string \| number` | `220` | Minimum height of the editing area. |
| `maxHeight` | `string \| number` | - | Maximum height of the editing area. |
| `ariaLabel` | `string` | `'Markdown editor'` | Accessible name shared by both editing surfaces. |
| `linkPrompt` | `(selectedText: string) => string \| Promise<string>` | - | Supplies the URL for the link action; without it, link does nothing. |

### Events

| Event | Params | Description |
|------|--------|-------------|
| `update:modelValue` | `(value: string)` | Fires when the content changes. |
| `change` | `(value: string)` | Fires together with `update:modelValue`. |
| `update:mode` | `(mode: MarkdownEditorMode)` | Fires on a mode switch, for `v-model:mode`. |
| `mode-change` | `(mode: MarkdownEditorMode)` | Fires together with `update:mode`. |
| `focus` | `()` | Fires when the editing surface gains focus. |
| `blur` | `()` | Fires when the editing surface loses focus. |

### Exposed Methods

| Method | Description |
|------|-------------|
| `focus()` | Focuses the current mode's editing surface. |
| `blur()` | Blurs the current editing surface. |
| `setMode(mode)` | Switches the mode. |
| `getMode()` | Returns the current mode. |
| `getValue()` | Returns the current Markdown. |
| `setValue(value)` | Writes Markdown, emits updates, and re-renders. |

### Types

:::TuffCodeBlock{lang="ts"}
---
code: |
  type MarkdownEditorMode = 'wysiwyg' | 'source' | 'preview'

  type MarkdownEditorToolbarActionKey =
    | 'heading' | 'bold' | 'italic' | 'strike' | 'quote' | 'code'
    | 'bulletList' | 'orderedList' | 'link' | 'undo' | 'redo'
---
:::

## Overview

- Passing `mode` makes the mode controlled; otherwise `defaultMode` seeds an internal mode.
- Source mode edits Markdown directly; WYSIWYG mode serializes the DOM back to Markdown on input.
- The toolbar is shared across modes and disabled in preview.
- In WYSIWYG and Source modes, `Cmd/Ctrl+B` and `Cmd/Ctrl+I` apply bold and italic, even when `toolbarActions` omits them.
- The mode switcher is a `role="group"` of toggle buttons; `aria-pressed` marks the active mode.
- `theme="auto"` follows the class and `data-theme` on `html` and `body`, falling back to light.

## Technologies

- Toolbar and mode buttons draw Carbon icons (`i-carbon-*`) by class name, generated by the host's UnoCSS.
- Source: `packages/tuffex/packages/components/src/markdown-editor/`.

<TuffDocSourceLink />
