Skip to content

Text Editor ​

A full-featured rich text editor with Word-like capabilities: font styling, color pickers, checklists, tables, image/video embeds, emoji, find & replace, footnotes, print, fullscreen, and more. Built on contenteditable with no external dependencies.

Arial
14
LH
Write something amazing...
vue
<script setup>
import { ref } from 'vue'
const content = ref('')
</script>

<template>
  <VxTextEditor v-model="content" placeholder="Write something amazing..." />
</template>

With Initial Content ​

Arial
14
LH
Start writing...
vue
<template>
  <VxTextEditor v-model="content" />
</template>

Image Upload with beforeUpload ​

The beforeUpload prop receives the selected File object. Your function should upload it to your server and return the image URL. The editor inserts the image once the URL is returned.

Arial
14
LH
Click the image button to upload, or drag & drop an image...
vue
<script setup>
import { ref } from 'vue'

const content = ref('')

async function handleUpload(file) {
  // Upload file to your server
  const formData = new FormData()
  formData.append('image', file)

  const response = await fetch('/api/upload', {
    method: 'POST',
    body: formData,
  })

  const data = await response.json()

  // Return the URL — the editor inserts <img src="url">
  return data.url
}
</script>

<template>
  <VxTextEditor
    v-model="content"
    :before-upload="handleUpload"
    :max-file-size="5 * 1024 * 1024"
    @upload-error="(err, file) => console.error(err, file)"
  />
</template>

How it works:

  1. User clicks image toolbar button → "Upload" tab → selects file from disk
  2. beforeUpload(file) is called with the raw File object
  3. Your function uploads to server and returns the URL string
  4. Editor inserts <img src="returned-url"> at cursor position

Also supports:

  • Drag & drop — drop images directly onto the editor
  • Paste — paste images from clipboard (screenshots, copied images)
  • URL tab — manually enter an image URL as fallback

Resizable Images ​

Click any image in the editor to select it. Drag the corner or side handles to resize. Press Delete or Backspace to remove a selected image.

Arial
14
LH
Drop an image here and then click it to resize...
vue
<template>
  <VxTextEditor v-model="content" :before-upload="handleUpload" />
  <!-- Click any inserted image to select it, then drag handles to resize -->
</template>

Table ​

Click the table button in the toolbar to open a grid picker. Hover to select size and click to insert.

Click the table icon in the toolbar to insert a table...
vue
<template>
  <VxTextEditor v-model="content" />
</template>

Right-click context menu on any cell:

  • Insert row above / below
  • Insert column left / right
  • Merge cell right — merges with the cell to the right (increases colspan)
  • Merge cell down — merges with the cell below (increases rowspan)
  • Split cell — appears when colspan > 1 or rowspan > 1, splits the merged cell back
  • Colspan / Rowspan controls — +/- buttons to set exact span values
  • Delete row / column / table

Column resize — hover near a column border to see the resize cursor, then drag to resize.

Font Family & Size ​

Use the font family and font size dropdowns to change typography. Select text first, then pick a font or size.

Arial
14
Start writing...
vue
<template>
  <VxTextEditor
    v-model="content"
    :toolbar="['fontFamily', 'fontSize', '|', 'bold', 'italic', '|', 'undo', 'redo']"
  />
</template>

Text & Highlight Color ​

Apply text color or background highlight color to selected text. Choose from 80 preset colors.

Start writing...
vue
<template>
  <VxTextEditor
    v-model="content"
    :toolbar="['bold', 'italic', '|', 'textColor', 'highlightColor', '|', 'undo', 'redo']"
  />
</template>

Checklist ​

Create interactive checklists. Click the checkbox area to toggle items.

Click the checklist button to add a to-do list...
vue
<template>
  <VxTextEditor
    v-model="content"
    :toolbar="['checklist', '|', 'bulletList', 'orderedList', '|', 'bold', 'italic', '|', 'undo', 'redo']"
  />
</template>

Video Embed ​

Embed YouTube or Vimeo videos. Click the video button, paste a URL, and the editor inserts a responsive iframe.

Click the video button to embed a YouTube or Vimeo video...
vue
<template>
  <VxTextEditor
    v-model="content"
    :toolbar="['video', 'image', 'link', '|', 'bold', 'italic', '|', 'undo', 'redo']"
  />
</template>

Import & Export ​

Import Word documents (.docx/.doc), export to Word, or export to PDF. The toolbar buttons use Vexel Icons.

Type content to export, or import a Word document...
vue
<script setup>
import { ref } from 'vue'
const content = ref('')
</script>

<template>
  <VxTextEditor
    v-model="content"
    :toolbar="[
      'bold', 'italic', 'underline', '|',
      'heading1', 'heading2', '|',
      'bulletList', 'orderedList', '|',
      'importWord', 'exportWord', 'exportPdf',
    ]"
  />
</template>

Features:

  • Import Word — Click the import icon to select a .docx or .doc file. Content is parsed and inserted into the editor.
  • Export Word — Downloads the editor content as a Word-compatible .doc file with proper formatting, tables, and styles.
  • Export PDF — Opens the browser print dialog for saving as PDF with a clean print stylesheet.

All Word-like toolbar items enabled — font styling, colors, lists, media, emoji, special characters, find & replace, footnotes, page breaks, print, and fullscreen.

Arial
14
LH
A fully-featured Word-like editor...
vue
<template>
  <VxTextEditor v-model="content" :before-upload="handleUpload" show-word-count show-character-count />
</template>

Custom Toolbar ​

Pass a custom array of toolbar items. Use '|' for separators.

Simple formatting only...
vue
<template>
  <VxTextEditor
    v-model="content"
    :toolbar="['bold', 'italic', 'underline', '|', 'bulletList', 'orderedList', '|', 'image', 'link', '|', 'undo', 'redo']"
    :before-upload="handleUpload"
  />
</template>

No Toolbar ​

Set :toolbar="false" to hide the toolbar entirely. Keyboard shortcuts still work.

Start writing...
vue
<template>
  <VxTextEditor v-model="content" :toolbar="false" />
</template>

Word & Character Count ​

Arial
14
LH
Start writing...
vue
<template>
  <VxTextEditor v-model="content" show-word-count show-character-count />
</template>

Min / Max Height ​

Arial
14
LH
Compact editor with scroll...
vue
<template>
  <VxTextEditor v-model="content" min-height="100px" max-height="300px" />
</template>

Read Only ​

Arial
14
LH
Start writing...
vue
<template>
  <VxTextEditor v-model="content" readonly />
</template>

Disabled ​

Arial
14
LH
Start writing...
vue
<template>
  <VxTextEditor model-value="<p>Disabled content</p>" disabled />
</template>

HTML Output ​

Arial
14
LH
Type to see HTML output below...
vue
<script setup>
import { ref } from 'vue'
const content = ref('')
</script>

<template>
  <VxTextEditor v-model="content" />
  <pre>{{ content }}</pre>
</template>

Toolbar Items ​

All available toolbar items:

ItemDescription
fontFamilyFont family dropdown (Arial, Times New Roman, Georgia, etc.)
fontSizeFont size dropdown (8px – 72px)
boldBold text
italicItalic text
underlineUnderline text
strikethroughStrikethrough text
heading1 – heading6Heading levels 1–6
textColorText color picker (80 preset colors)
highlightColorBackground highlight color picker
bulletListUnordered list
orderedListOrdered list
checklistInteractive checklist with checkboxes
blockquoteBlockquote
codeInline code
codeBlockCode block
linkInsert/edit link
imageUpload image or insert by URL
videoEmbed YouTube or Vimeo video
tableInsert table with grid picker; right-click cells for row/column/merge actions
emojiEmoji picker (80 emojis)
specialCharsSpecial characters picker (60 characters)
alignLeftAlign left
alignCenterAlign center
alignRightAlign right
alignJustifyJustify
indentIncrease indent
outdentDecrease indent
lineHeightLine height picker (1.0 – 3.0)
horizontalRuleHorizontal rule
pageBreakInsert page break
footnoteInsert numbered footnote
subscriptSubscript
superscriptSuperscript
findReplaceFind & replace bar with next/prev navigation
undoUndo
redoRedo
clearClear formatting
printPrint editor content
fullscreenToggle fullscreen editing mode
|Separator

Props ​

PropTypeDefaultDescription
modelValuestring''HTML content (v-model)
placeholderstring'Start writing...'Placeholder text
disabledbooleanfalseDisable the editor
readonlybooleanfalseRead-only mode
toolbarTextEditorToolbarItem[] | falseDefault toolbarToolbar configuration
minHeightstring'200px'Minimum editor height
maxHeightstringundefinedMaximum editor height (enables scroll)
showCharacterCountbooleanfalseShow character count
showWordCountbooleanfalseShow word count
autofocusbooleanfalseAuto-focus on mount
beforeUpload(file: File) => Promise<string> | stringundefinedUpload handler — receives file, must return image URL
acceptstring'image/*'Accepted file types for the file input
maxFileSizenumberundefinedMaximum file size in bytes

Events ​

EventPayloadDescription
update:modelValuestringEmitted when content changes
focusFocusEventEmitted when editor receives focus
blurFocusEventEmitted when editor loses focus
changestringEmitted when content changes
uploadError(error: Error, file: File)Emitted when image upload fails or exceeds size limit

Exposed Methods ​

MethodDescription
focus()Focus the editor
blur()Blur the editor
getHTML()Get current HTML content
getText()Get current plain text content
exec(command, value?)Execute a document command