Vue editor

Rich text editing for Vue.

Bind HTML with v-model or build your own interface with the composable.

Details

Bind HTML with v-model on the drop-in component, or take full control of the UI with the useRichTextEditor composable. One engine underneath: AI Toolkit, per-node CRDT collaboration, tracked changes, and clean HTML output.

Vue focus

Composition-API-first, Options-API friendly.

v-model bindingmodelValue accepts HTML or the structured document; valueFormat picks which one your app round-trips.
Composable for custom UIuseRichTextEditor returns mountRef, the live editor, and a reactive state for your own toolbar buttons.
Typed template refsThe exposed surface covers getHTMLCode, getJSON/setJSON, focus, statistics, outline, and plugin accessors.
Sony
Intel
Nokia
Siemens
IBM
Microsoft

Install once, bind with v-model

One npm package ships the engine, the Vue 3 bindings, and the plugin bundle. Vue 3 is a peer dependency.

npm install @richscripts/richtexteditor

Option 1 — the drop-in component

Standard v-model: the component emits updates as the user types, and any editor option passes through :config — toolbar presets, height, upload endpoints, AI settings.

<script setup>
import { ref } from "vue";
import { RichTextEditor } from "@richscripts/richtexteditor/vue";

const html = ref("<p>Draft your update...</p>");
</script>

<template>
  <RichTextEditor v-model="html" :config="{ height: 400 }" />
</template>

Option 2 — bring your own UI with the composable

useRichTextEditor gives you a mountRef for your own element plus a reactive state (bold, canUndo, ...) that updates as the selection moves. Use @mousedown.preventso toolbar clicks don’t steal focus from the editor.

<script setup>
import { useRichTextEditor } from "@richscripts/richtexteditor/vue";

// mountRef goes on your own element; state re-renders your buttons live.
const { mountRef, editor, state } = useRichTextEditor({ value: "<p>Hi</p>" });
</script>

<template>
  <button :class="{ 'is-active': state.bold }"
          @mousedown.prevent="editor.run('bold')">Bold</button>
  <button :disabled="!state.canUndo"
          @mousedown.prevent="editor.run('undo')">Undo</button>

  <div ref="mountRef"></div>
</template>

Reading and writing content imperatively

A template ref exposes the typed surface: HTML in/out, the structured JSON document model, text statistics, document outline, and accessors for AI Toolkit, comments, tracked changes, and collaboration.

<script setup>
import { ref } from "vue";
import { RichTextEditor } from "@richscripts/richtexteditor/vue";

const editorRef = ref(null);

function save() {
  const html = editorRef.value?.getHTMLCode() ?? "";
  const json = editorRef.value?.getJSON();   // structured document
  // send html / json to your API ...
}
</script>

<template>
  <RichTextEditor ref="editorRef" :default-value="'<p></p>'" />
  <button @click="save">Save</button>
</template>

Why teams pick it over assembling an editor stack

  • Everything is included: AI Toolkit (bring your own key), per-node Yjs CRDT collaboration, tracked changes, comments, and revision history ship in the same package — no premium add-on tiers.
  • Clean HTML out: publish-ready markup plus a structured JSON model for validation and server rendering via the package’s server entry.
  • Perpetual license from $129: no subscription and no per-seat AI pricing — see pricing and the Quill / CKEditor comparisons.

Guides for Vue, JavaScript: uploads, gallery and files

Tested server code for each step, one problem per page.

All Vue guides

Using something else? There are matching guides for React, Next.js, Angular, Svelte, Blazor, ASP.NET Core, PHP, and plain JavaScript.