Skip to content

MazMarkdownEditor ​

MazMarkdownEditor is a GitHub-style markdown editor with Write/Preview/Split tabs, a configurable formatting toolbar, optional line numbers, and a sanitized preview. It shares the same states, labels and theming as MazTextarea, is SSR-friendly, and supports custom renderers.

Before use it, you should install the MazUi plugin in your project, follow instructions in Getting Started

Installation requirement ​

The preview relies on marked for parsing and dompurify for sanitization. Both are loaded lazily (only when the preview is rendered), so install them in your project:

bash
pnpm add marked dompurify
bash
npm install marked dompurify
bash
yarn add marked dompurify

If they are not installed, the preview falls back to a safe, escaped plain-text block. You can also provide your own renderer with the renderFunction prop to avoid these dependencies entirely.

Basic usage ​

The component exposes a v-model bound to the raw markdown string and two tabs: Write (textarea) and Preview (rendered, sanitized HTML).

Toolbar ​

The formatting toolbar is opt-in. Set toolbar to true to display the full toolbar. Buttons act on the current textarea selection and preserve the native undo/redo history (Cmd/Ctrl + Z).

Available actions ​

The full toolbar exposes the following action keys:

KeyResult
headingHeading dropdown (#, ##, ###)
bold**bold**
italic_italic_
strikethrough~~strikethrough~~
quote> quote
code`inline code`
codeBlockfenced ``` code block
link[text](url)
image![alt](url)
bulletList- item
orderedList1. item
checkList- [ ] task
tablemarkdown table skeleton

Configure the toolbar ​

Pass an ordered array of action keys to display only a subset (and control their order):

Keyboard shortcuts ​

Classic markdown shortcuts are enabled by default and work whenever the textarea is focused. They preserve the native undo/redo history. The toolbar buttons also display their shortcut in the tooltip. Use mod for Cmd on macOS and Ctrl elsewhere.

ShortcutAction
mod + BBold
mod + IItalic
mod + Shift + XStrikethrough
mod + KLink
mod + EInline code
mod + Shift + ECode block
mod + Shift + .Quote
mod + Shift + 8Bulleted list
mod + Shift + 7Numbered list
mod + Shift + LTask list
mod + Alt + 1/2/3Heading 1/2/3

Disable them with :shortcuts="false":

vue
<template>
  <MazMarkdownEditor v-model="content" toolbar :shortcuts="false" />
</template>

TIP

Image and table insertions have no default shortcut (to avoid clashing with browser shortcuts). Use the toolbar buttons or the toolbar slot helpers for those.

List continuation ​

Pressing Enter inside a list automatically inserts the next marker, just like a desktop markdown editor:

  • Bulleted lists (-, *, +) repeat the marker.
  • Numbered lists increment the index (1. → 2.).
  • Task lists insert a fresh unchecked box (- [ ] ).
  • Indentation is preserved.

Pressing Enter again on an empty item removes the marker and exits the list. This works out of the box, no configuration required.

Label & assistive text ​

Like MazTextarea, the editor supports a static top-label (or label), the required asterisk and an assistive-text displayed below the editor.

Markdown is supported

States ​

Use error, success, warning, disabled and readonly to reflect validation states, consistent with the other form components.

This field has an error
Looks good!

Split mode ​

A third tab displays the editor and the preview side by side. Switch to it from the toolbar tabs, or control it with v-model:mode ('write' | 'preview' | 'split'). On small screens the two panes stack vertically.

Nothing to preview

Line numbers ​

Enable the line-numbers prop to display a gutter on the left of the editor. Numbers reflect logical lines and stay in sync with the textarea scroll.

Custom renderer ​

Provide a render-function to use your own markdown engine (e.g. markdown-it, a Nuxt Content renderer, or a server-side pipeline). It receives the raw markdown and returns an HTML string (sync or async). The result is still sanitized when sanitize is enabled.

Sanitization ​

By default, the rendered HTML is sanitized with DOMPurify to prevent XSS. Disabling it (:sanitize="false") renders the raw output of the renderer; only do this when the markdown source is fully trusted.

vue
<template>
  <!-- Trusted content only -->
  <MazMarkdownEditor v-model="content" :sanitize="false" />
</template>

Controlled mode ​

The active tab is available through v-model:mode ('write' | 'preview' | 'split').

vue
<template>
  <MazMarkdownEditor v-model="content" v-model:mode="mode" />
  <p>Current tab: {{ mode }}</p>
</template>

<script lang="ts" setup>
  import { ref } from 'vue'
  import MazMarkdownEditor from 'maz-ui/components/MazMarkdownEditor'

  const content = ref('')
  const mode = ref<'write' | 'preview' | 'split'>('write')
</script>

Custom translations ​

The tab labels, the empty-preview text and the toolbar button labels come from the @maz-ui/translations package (markdownEditor.*). You can override any key per-instance with the translations prop without touching the global locale:

For app-wide translations, set up the maz-ui translations plugin and the component will pick up your locale automatically.

Accessibility ​

The write / preview / split switcher follows the WAI-ARIA tabs pattern: it is a tablist named by the name prop, the editor and the preview are its tabpanels. Only the selected mode is in the tab sequence, ← / → (reversed in RTL), Home and End switch the mode.

Props ​

NameDescriptionTypeRequiredDefault
styleStyle attribute of the component root elementNative typeNoundefined
classClass attribute of the component root elementNative typeNoundefined
model-valuev-model
stringNoundefined
idThe id of the textareastringNoundefined
nameThe name of the textareastringNoundefined
labelStatic label displayed above the editorstringNoundefined
placeholderThe placeholder of the textareastringNoundefined
requiredIf the editor is requiredbooleanNoundefined
disabledIf the editor is disabledbooleanNoundefined
readonlyIf the editor is readonlybooleanNoundefined
errorIf the editor has an errorbooleanNoundefined
successIf the editor has a successbooleanNoundefined
warningIf the editor has a warningbooleanNoundefined
colorThe color of the editorMazColorNoundefined
rounded-sizeSize radius of the component's borderMazRoundedSizeNomd
top-labelStatic label displayed above the editor. Unlike a floating label, this remains fixedstringNoundefined
assistive-textHelper text displayed below the editor to provide additional context or validation feedback
Example: "Markdown is supported"
stringNoundefined
toolbarShow the formatting toolbar. Pass true for the full toolbar, or an ordered array of action keys to display only a subset (and control their order).boolean | MazMarkdownEditorToolbarAction[]Nofalse
line-numbersDisplay line numbers in a gutter on the left of the editorbooleanNofalse
shortcutsEnable keyboard shortcuts for the toolbar actions (e.g. Cmd/Ctrl+B for bold).booleanNotrue
sanitizeSanitize the rendered preview HTML with DOMPurifybooleanNotrue
render-functionCustom markdown renderer. Receives the raw markdown and returns an HTML string (sync or async). Falls back to marked when omitted. The result is still sanitized when sanitize is enabled.TSFunctionTypeNoundefined
marked-optionsOptions forwarded to marked when using the default rendererRecordNoundefined
rowsMinimum number of visible rows of the editor textareanumberNo6
translationsCustom translations for the component. Override any key independently.DeepPartial<MazUiTranslationsNestedSchema['markdownEditor']>Noundefined

Events ​

Event namePropertiesDescription
update:model-valuevalue string | undefined - The markdown valueEmitted when the markdown value changes
inputvalue string | undefined - The markdown valueEmitted when the markdown value changes
focusevent FocusEvent - The focus eventEmitted when the textarea is focused
blurevent FocusEvent - The blur eventEmitted when the textarea is blurred
changeevent Event - The change eventEmitted when the textarea value changes

Slots ​

NameDescriptionBindings
labelReplace the static label displayed above the editor
toolbarReplace the toolbar content (only rendered when the toolbar is enabled and not in preview mode)mode MazMarkdownEditorMode - The current editor mode
wrap-selection Function - Wrap the current selection with the given markers
prefix-lines Function - Prefix every selected line with the given string
apply-heading Function - Apply a heading of the given level to the selected lines
insert-link Function - Insert a markdown link at the selection
insert-image Function - Insert a markdown image at the selection
insert-code-block Function - Insert a fenced code block at the selection
insert-table Function - Insert a markdown table at the selection
empty-previewContent displayed in the preview pane when there is nothing to render

Expose ​

textarea ​

The underlying textarea element

mode ​

The current editor mode (write / preview / split)

renderPreview ​

Programmatically re-render the markdown preview

focus ​

Focus the editor textarea