@rozie-ui/tiptap-vue

Idiomatic Vue rich-text editor — one Rozie source compiled to Vue wrapping TipTap.
2,146 1
Install
npm install @rozie-ui/tiptap-vue
Latest Version:0.5.4
Vue:3
License:MIT
Last Updated:Oct 15, 2026
Links: GitHub  ·  npm
Maintainer: serpentblade

@rozie-ui/tiptap-vue

Idiomatic vue TipTap — a cross-framework rich-text editor component compiled from one Rozie source wrapping TipTap (the ProseMirror-based headless editor). Two-way html content binding, a batteries-included toolbar (or bring your own via the toolbar slot), a 25-verb imperative command handle, and editorProps/extensions passthroughs. This package is generated; do not edit src/ by hand.

Install

npm i @rozie-ui/tiptap-vue

Peer dependencies: @tiptap/core, @tiptap/starter-kit, @tiptap/extensions and @tiptap/extension-bubble-menu (all ^3) + vue. Install them alongside this package. Optional, loaded only when used: @tiptap/extension-character-count (maxLength / #count), @tiptap/extension-image (uploadImage) and @tiptap/extension-floating-menu (the floatingMenu slot).

Usage

<script setup lang="ts">
import { ref } from 'vue';
import TipTap from '@rozie-ui/tiptap-vue';

const html = ref('<p>Hello <strong>world</strong></p>');
</script>

<template>
  <TipTap v-model:html="html" placeholder="Start writing…" />
</template>

Props

Name Type Default Two-way (model)
html String "<p>Start writing…</p>" ✓
editable Boolean true
placeholder String ""
autofocus Boolean false
editorClass String ""
ariaLabel String "Rich text editor"
editorProps Object {}
extensions Array []
starterKit Object {}
nodeSpecs Array []
uploadImage Function null
maxLength Number null
enforceMaxLength Boolean false
bubbleMenuShouldShow Function null

Events

Event Description
update The document changed — payload is the new HTML string.
selectionUpdate The selection (caret/range) moved.
focus The editor gained focus.
blur The editor lost focus.
ready The editor exists — the live TipTap Editor instance. Fires once per mount. Handle verbs (focusEditor(), setContent(), …) work from here on; with an optional extension in use (maxLength, uploadImage, the floatingMenu slot) construction waits for its import, so this is the moment to act rather than a fixed delay.
error An optional extension (floatingMenu, image, count) failed to load via dynamic import() — payload is { extension, error }. The editor still constructs WITHOUT that extension (degrade); a network blip never leaves a mounted <TipTap> permanently blank.

Imperative handle

Beyond props, the component exposes imperative methods (declared once in the Rozie source via $expose). Grab a handle with the native ref mechanism and call them directly:

<script setup>
import { ref } from 'vue';
const editor = ref();        // template ref
</script>

<template>
  <TipTap ref="editor" />
  <button @click="editor.toggleBold()">Bold</button>
</template>
Method Description
getEditor Return the underlying TipTap Editor instance for direct API access (commands, state, schema, extension storage).
focusEditor Focus the editor — place the caret in the document.
blurEditor Blur the editor — remove focus from the document.
getHTML Return the current document serialized as an HTML string.
getJSON Return the current document as a ProseMirror JSON object (JSONContent).
getText Return the current document as a plain-text string (word/char counts, search indexing, plaintext export).
setContent Replace the document content — setContent(html). Echo-guarded: reflects into the bound html model without bouncing an extra update.
clearContent Clear the document to an empty paragraph (reflects the empty value into the bound html model).
toggleBold Toggle bold on the current selection.
toggleItalic Toggle italic on the current selection.
toggleHeading Toggle a heading at the given level — toggleHeading(level) (defaults to 1).
toggleBulletList Toggle a bullet list at the current selection.
toggleUnderline Toggle underline on the current selection.
toggleOrderedList Toggle an ordered (numbered) list at the current selection.
undo Undo the last change.
redo Redo the last undone change.
chain Return a focused TipTap command chain for composing commands — e.g. chain().toggleBold().toggleItalic().run() (null before mount).
isActive Whether a mark/node is active in the current selection — isActive(name, attrs?) (e.g. isActive("heading", { level: 2 })). Drives custom-toolbar active styling. False before mount.
can Return the command-availability chain — can().chain().focus().toggleBold().run() returns a boolean — for enabling/disabling custom-toolbar buttons. null before mount.
isEmpty Whether the document is empty — drives empty-state UI and submit-gating. true before mount.
getCharacterCount Return the current character count. Reads the CharacterCount extension's live storage when registered (maxLength set or the #count slot filled), else falls back to getText().length. Always a number — 0 before mount.
getWordCount Return the current word count. Reads the CharacterCount extension's live storage when registered, else falls back to a whitespace-split count of getText(). Always a number — 0 before mount.
openLinkEditor Open the link editor on the current selection (create mode) — the imperative equivalent of clicking the toolbar Link button. Surfaces the editor prefilled with any existing link href; no-op before mount.
setLink Apply or replace a link on the current selection, widening to the whole link mark first — setLink({ href }), with any additional stock attrs (target, rel, class, title) forwarded verbatim. An attrs object without a non-empty href is ignored. Attrs the registered Link extension does not declare are dropped by the extension itself — persisting a custom attribute requires Link.extend({ addAttributes }) via the extensions prop. No-op before mount.
unsetLink Remove the link mark from the current selection, widening to the whole link first. No-op before mount.

Slots

When you fill the toolbar slot the internal toolbar is replaced by your own UI, which receives the live editor so its buttons can drive editor.chain().focus()…run():

<template #toolbar="{ editor }"> … </template>
Slot Params
count characters, words, maxLength, over
toolbar editor
bubbleMenu editor
floatingMenu editor
linkEditor editor, href, attrs, setLink, unsetLink, close
nodeView node, selected, updateAttributes, getPos, editor, contentDOM

Related Packages

@tiaohsun/vue-rich-text-editor

A thin, batteries-included Vue 3 wrapper around Tiptap v3 — editor component, to...

1,299 0
@shamimsofte/universal-editor-vue2

Vue 2 adapter for Universal Rich Text Editor (Vue 2.6+ & 2.7)

571 0
@shamimsofte/universal-editor-vue3

Vue 3 adapter and components for Universal Editor

564 0
guodu-tiptap

A WYSIWYG rich-text editor using tiptap

842 18
@markweave/vue2

Vue 2 adapter for the Markweave Markdown-first WYSIWYG editor.

9,500 1

Version History

Version Released Vue License
0.5.4 ^3.4 MIT
0.5.3 ^3.4 MIT
0.5.2 ^3.4 MIT
0.5.1 ^3.4 MIT
0.4.0 ^3.4 MIT