Vue 3 components and composables for building rich text editors with tiptap
npx @tessl/cli install tessl/npm-tiptap--vue-3@3.4.0@tiptap/vue-3 provides Vue 3 components and composables for building rich text WYSIWYG editors with tiptap. It's a headless wrapper around ProseMirror that offers complete customization while handling complex editor state management through Vue's reactive system.
npm install @tiptap/vue-3 @tiptap/core @tiptap/pmimport {
Editor,
EditorContent,
useEditor,
NodeViewContent,
NodeViewWrapper,
VueRenderer,
VueNodeViewRenderer,
VueMarkViewRenderer
} from "@tiptap/vue-3";For CommonJS:
const {
Editor,
EditorContent,
useEditor,
NodeViewContent,
NodeViewWrapper,
VueRenderer,
VueNodeViewRenderer,
VueMarkViewRenderer
} = require("@tiptap/vue-3");Menu components:
import { BubbleMenu, FloatingMenu } from "@tiptap/vue-3/menus";All @tiptap/core exports are also available:
import { Node, Mark, Extension, Command } from "@tiptap/vue-3";<template>
<div v-if="editor">
<BubbleMenu :editor="editor">
<button @click="editor.chain().focus().toggleBold().run()">Bold</button>
</BubbleMenu>
<EditorContent :editor="editor" />
</div>
</template>
<script setup>
import { useEditor, EditorContent } from "@tiptap/vue-3";
import { BubbleMenu } from "@tiptap/vue-3/menus";
import StarterKit from "@tiptap/starter-kit";
const editor = useEditor({
content: '<p>Hello World!</p>',
extensions: [StarterKit],
});
</script>@tiptap/vue-3 consists of several key components:
useEditor composable for lifecycle managementCore editor functionality with Vue 3 reactive state integration. Handles editor lifecycle, content management, and state synchronization.
class Editor extends CoreEditor {
constructor(options?: Partial<EditorOptions>);
get state(): EditorState;
get storage(): Storage;
registerPlugin(plugin: Plugin, handlePlugins?: (newPlugin: Plugin, plugins: Plugin[]) => Plugin[]): EditorState;
unregisterPlugin(nameOrPluginKey: string | PluginKey): EditorState | undefined;
}
function useEditor(options?: Partial<EditorOptions>): Ref<Editor | undefined>;Vue 3 components for rendering editor content and UI elements. Includes content rendering, node view wrappers, and utility components.
const EditorContent: DefineComponent<{
editor: PropType<Editor>;
}>;
const NodeViewContent: DefineComponent<{
as?: PropType<string>;
}>;
const NodeViewWrapper: DefineComponent<{
as?: PropType<string>;
}>;Interactive menu components that float above or beside editor content. Supports bubble menus (appear on selection) and floating menus (appear on empty lines).
const BubbleMenu: DefineComponent<{
pluginKey?: PropType<string | Object>;
editor: PropType<Editor>;
updateDelay?: PropType<number>;
resizeDelay?: PropType<number>;
options?: PropType<Object>;
shouldShow?: PropType<Function>;
}>;
const FloatingMenu: DefineComponent<{
pluginKey?: PropType<string | Object>;
editor: PropType<Editor>;
options?: PropType<Object>;
shouldShow?: PropType<Function>;
}>;Utilities for creating custom Vue-based node and mark views. Enables embedding Vue components directly into editor content with full component lifecycle support.
class VueRenderer {
constructor(component: Component, options: VueRendererOptions);
get element(): Element | null;
get ref(): any;
updateProps(props: Record<string, any>): void;
destroy(): void;
}
function VueNodeViewRenderer(component: Component, options?: VueNodeViewRendererOptions): NodeViewRenderer;
function VueMarkViewRenderer(component: Component, options?: VueMarkViewRendererOptions): MarkViewRenderer;Complete tiptap core functionality including commands, helpers, extensions, and utilities. Provides the full editor API for content manipulation, state management, and extension development.
// Re-exported from @tiptap/core
class Extension { /* ... */ }
class Node { /* ... */ }
class Mark { /* ... */ }
// Commands (55+ functions)
function insertContent(content: Content): Command;
function toggleMark(typeOrName: string | MarkType, attributes?: {}): Command;
function setTextSelection(position: number | { from: number; to?: number }): Command;
// Helpers (54+ functions)
function generateHTML(doc: JSONContent, extensions: Extensions): string;
function generateJSON(html: string, extensions: Extensions): JSONContent;
function isActive(state: EditorState, typeOrName: string | NodeType | MarkType, attributes?: {}): boolean;interface ContentComponent {
ctx: ComponentPublicInstance;
}
interface VueRendererOptions {
editor: Editor;
props?: Record<string, any>;
}
interface VueNodeViewRendererOptions extends NodeViewRendererOptions {
update?: ((props: {
oldNode: ProseMirrorNode;
oldDecorations: readonly Decoration[];
oldInnerDecorations: DecorationSource;
newNode: ProseMirrorNode;
newDecorations: readonly Decoration[];
innerDecorations: DecorationSource;
updateProps: () => void;
}) => boolean) | null;
}
interface VueMarkViewRendererOptions extends MarkViewRendererOptions {
as?: string;
className?: string;
attrs?: { [key: string]: string };
}
// All @tiptap/core types are also available
type EditorOptions = { /* core editor configuration */ };
type JSONContent = { /* document content structure */ };
type Extensions = Extension[];