Component

Vue WYSIWYG Editor Field

<DomWysiwyg>

A textarea-shaped rich text field powered by DomDocumentEditor, with headings, language-aware highlighted code blocks, tables, simple v-model wiring, and no collaboration or AI review rail by default.

Playground

Try every prop live

WYSIWYG field playground

Adjust the props to explore sizing, content, and behaviour.

The editor mounts in the browser.

Edit link

Add a destination URL for the selected text.

Embed video

Paste a YouTube, Vimeo, or iframe-safe video URL.

Playground.vuevue
Install
npm install @getdom/studio
vue
<script setup>
import '@getdom/studio/style.css';
import { reactive } from 'vue';
import { DomWysiwyg } from '@getdom/studio';

const data = reactive({
		"modelValue": {
			"type": "doc",
			"content": [
				{
					"type": "heading",
					"attrs": {
						"level": 1
					},
					"content": [
						{
							"type": "text",
							"text": "Customer launch note"
						}
					]
				},
				{
					"type": "paragraph",
					"content": [
						{
							"type": "text",
							"text": "The July release gives teams one place to draft product copy, review AI suggestions, and keep the final document structured for publishing."
						}
					],
					"attrs": {
						"level": ""
					}
				},
				{
					"type": "paragraph",
					"content": [
						{
							"type": "text",
							"text": "The current draft needs a warmer introduction, a shorter benefits section, and one image from the product media library before it is ready to share."
						}
					],
					"attrs": {
						"level": ""
					}
				}
			]
		},
		"id": "",
		"name": "",
		"label": "",
		"description": "",
		"placeholder": "",
		"required": false,
		"disabled": false,
		"readOnly": false,
		"invalid": false,
		"errors": [],
		"visible": true,
		"validators": [],
		"validateOnBlur": true,
		"chrome": "field",
		"output": "json",
		"editable": true,
		"title": "",
		"status": "",
		"tools": [
			"undo",
			"redo",
			"paragraph",
			"heading1",
			"heading2",
			"heading3",
			"bold",
			"italic",
			"underline",
			"bulletList",
			"orderedList",
			"blockquote",
			"codeBlock",
			"link",
			"table"
		],
		"customTools": [],
		"showToolbar": true,
		"showSlashMenu": true,
		"minHeight": "16rem"
	});
</script>

<template>
	<DomWysiwyg
		v-bind="data"
		@update:modelValue="data.modelValue = $event"
	/>
</template>

Reference

Props

Control props

NameTypeTSDefaultDescription
modelValueobject | stringRecord<string, unknown>() => …Controlled editor content. JSON is preferred; HTML strings are accepted for simple imports.
output'json' | 'html'string'json'Value emitted through update:modelValue.
editablebooleanbooleantrueAllow editing and toolbar commands.
titlestringstring''Accessible editor title. Defaults to the field label.
statusstringstring''Optional save or validation status label.
toolsarrayArray<unknown>() => …Built-in toolbar tool ids to show.
customToolsarrayArray<unknown>[]Additional toolbar actions emitted through tool-action.
showToolbarbooleanbooleantrueShow the WYSIWYG toolbar.
showSlashMenubooleanbooleantrueOpen the block command menu when the user types / at the start of a block.
minHeightstringstring'16rem'Minimum height for the editable field.

Field props

NameTypeTSDefaultDescription
idstringstring''Optional ID override. By default parent forms derive the input ID from the field path using underscores.
namestringstring''Local field name. Parent forms derive the full field path and native HTML name from the form hierarchy.
labelstringstring''Visible field label.
descriptionstringstring''Optional helper copy below the field.
placeholderstringstring''Placeholder shown when the control is empty.
requiredbooleanbooleanfalseMark the field as required.
disabledbooleanbooleanfalseDisable field interaction.
readOnlybooleanbooleanfalseShow the value but prevent editing.
invalidbooleanbooleanfalseMark the field invalid.
errors
ts
[
	{
		name: "Validation name",
		message: "Error message",
	}
]
array | object | stringArray<ErrorsItem
type ErrorsItem = {
	name?: string; // Name
	message?: string; // Message
};
>
[]Validation errors for this field.
visiblebooleanbooleantrueShow or hide the field.
validatorsarrayArray<unknown>[]Validators attached to this field. Use functions in Vue code, or serializable records such as { name: "minLength", props: { min: 2 } } in generated schemas.
validateOnBlurbooleanbooleantrueRun validators when the field loses focus.
chrome'field' | 'none' | falsestring'field'Render default field chrome, or hide chrome while keeping form state wiring.

Auto-generated from WYSIWYG field.props and inline _edit hints.

Events

NamePayloadDescription
@update:modelValueRecord<string, unknown> | stringFired with JSON or HTML content depending on the output prop.
@changeDocumentEditorChangePayloadFired with JSON, HTML, and plain text whenever the editor changes.
@selection-changeDocumentEditorSelectionPayloadFired when the editor selection changes.
@tool-action({ tool, editor })Fired when a custom toolbar tool is activated.
@ready({ editor })Fired after the browser-only editor runtime mounts.
@runtime-errorErrorFired when the editor runtime cannot mount.
@focusFocusEventFired when the editable document receives focus.
@blurFocusEventFired when the editable document loses focus.

Names auto-detected from defineEmits and source emit() calls; payload and description from __doc.events when present.