# Introduction Source: /getting-started/introduction > What Echo Editor is, what it ships with and how it is built. Echo Editor is a WYSIWYG rich-text editor for **Vue 3**. It wraps [Tiptap 3](https://tiptap.dev) (and therefore ProseMirror) in a ready-to-use component with a toolbar, bubble menus, a slash menu and a drag handle — all styled with [shadcn-vue](https://shadcn-vue.com) and Tailwind CSS 4. ## Highlights - **Batteries included** — 40+ extensions: headings, lists, task lists, tables, columns, code blocks with syntax highlighting, images, video, embeds, find & replace, HTML source editing, print, fullscreen and more. - **Fast** — Tiptap is shared with your app instead of bundled, feature UIs load on demand, and the toolbar re-evaluates at most once per animation frame. See [Performance](/guide/performance). - **Markdown & export** — `v-model` in HTML, JSON, text or Markdown, plus export to PDF, Markdown, HTML, RTF, text and JSON. - **Collaboration** — Y.js-powered real-time editing with remote carets, shipped as a separate entry point. - **AI** — an inline AI menu that streams completions from any model or backend. - **Accessible & international** — labelled controls, keyboard-navigable toolbar, screen-reader announcements, 11 languages and RTL support. - **Extensible** — every button comes from an extension, and `definePlugin()` bundles your own extensions, buttons, slash commands and translations. ## How it fits together | Layer | Responsibility | | --- | --- | | `` | Component: creates the Tiptap editor, renders toolbar, menus and dialogs, syncs `v-model`. | | Extensions | Tiptap extensions extended with a `button` view — each one contributes schema, commands, shortcuts **and** its toolbar UI. | | Composables | `useEditorState`, `useTheme`, `useTiptapStore`, `useLocale` for building your own UI around the editor. | | Plugins | `definePlugin()` packages extensions, buttons, slash commands and translations for reuse. | ## Requirements - Vue `3.5+` - A bundler that understands ES modules and CSS imports (Vite, Nuxt, Rsbuild, webpack 5 …) - Node.js `20.19+` for development > Coming from `0.x`? Read the [migration guide](/getting-started/migration) — version 1.0 moves to Tiptap 3. # Installation Source: /getting-started/installation > Install the package and import the styles. ### Install the package ```bash pnpm add vue-echo-editor ``` Tiptap, ProseMirror and the UI primitives are regular dependencies and are installed automatically. They are **not** bundled into Echo Editor, so if your app already uses Tiptap 3 you get a single shared copy. ### Import the styles Import the stylesheet once, for example in `main.ts`: ```ts [main.ts] import 'vue-echo-editor/style.css' ``` ### (Optional) register the component globally ```ts [main.ts] import { createApp } from 'vue' import { EchoEditorPlugin } from 'vue-echo-editor' import 'vue-echo-editor/style.css' import App from './App.vue' createApp(App).use(EchoEditorPlugin).mount('#app') ``` This registers `` (and the legacy `` tag). You can also import `EchoEditor` directly where you use it — that is what the rest of these docs do. ## Optional peer dependencies Only install these when you use the matching feature: | Feature | Packages | | --- | --- | | [Collaboration](/guide/collaboration) | `yjs`, `@tiptap/y-tiptap`, `@tiptap/extension-collaboration`, `@tiptap/extension-collaboration-caret` and a provider such as `y-websocket` | ```bash pnpm add yjs y-websocket @tiptap/y-tiptap @tiptap/extension-collaboration @tiptap/extension-collaboration-caret ``` ## Package entry points | Import | Contents | | --- | --- | | `vue-echo-editor` | Component, extensions, composables, locales, plugin API | | `vue-echo-editor/collaboration` | `CollaborationKit`, `CollaborationUsers`, `useCollaborationUsers` | | `vue-echo-editor/style.css` | Editor styles (scoped to `.echo-editor`) | Both ESM and CommonJS builds are published, with full TypeScript declarations. # Quick start Source: /getting-started/quick-start > Render your first editor with v-model in under a minute. ## A minimal editor ```vue [RichEditor.vue] ``` `BaseKit` is required: it provides the document model, paragraphs, placeholder, character count and the bubble menu. Everything else is opt-in — **the toolbar is built from the extensions you register**, in the order you register them. ## Choose an output format ```vue ``` ## Group toolbar buttons Every extension accepts `spacer` (a separator before its button) and `divider` (a separator after it): ```ts const extensions = [ BaseKit, History, Heading.configure({ spacer: true }), Bold, Italic, Underline, Link.configure({ spacer: true }), BulletList, OrderedList, ] ``` Hide an extension's button while keeping its functionality with `toolbar: false`: ```ts Bold.configure({ toolbar: false }) // Mod-B still works ``` ## Access the Tiptap editor ```vue ``` You can also use a template ref: `editorRef.value.editor`. ## Next steps Every prop, event and slot. The full extension catalogue. Use Echo Editor in a Nuxt app. Markdown as your v-model. # Nuxt Source: /getting-started/nuxt > Use Echo Editor in a Nuxt 3 / Nuxt 4 application. Echo Editor is a browser component (it needs the DOM for ProseMirror), so render it on the client. ### Install ```bash pnpm add vue-echo-editor ``` ### Add the styles ```ts [nuxt.config.ts] export default defineNuxtConfig({ css: ['vue-echo-editor/style.css'], build: { transpile: ['vue-echo-editor'], }, }) ``` ### Create a client-only component Name the file with a `.client.vue` suffix, or wrap the editor in ``: ```vue [components/RichEditor.client.vue] ``` ### Use it ```vue [pages/index.vue] ``` ## Rendering stored content on the server To display saved documents during SSR (for SEO or a read-only view) you do not need the editor. Render the stored HTML inside an element with the `EchoContentView` class so it gets the editor's typography: ```vue ``` > Always sanitize user-generated HTML on the server (for example with DOMPurify or `sanitize-html`) before rendering it with `v-html`. ## Colour mode Pass Nuxt's colour mode to the editor so it follows your site theme: ```vue ``` # Migrating to v1 Source: /getting-started/migration > Upgrade from Echo Editor 0.x (Tiptap 2) to 1.x (Tiptap 3). Version 1.0 moves Echo Editor to **Tiptap 3** and modernises the build. Most apps only need to bump the package; custom extensions and deep integrations may need the changes below. ## TL;DR ```bash pnpm add vue-echo-editor@^1 ``` - Your `` usage, props, `v-model` and built-in extensions keep working. - If you wrote **custom Tiptap extensions**, follow the [Tiptap v2 → v3 upgrade guide](https://tiptap.dev/docs/guides/upgrade-tiptap-v2). - The default UI language is now **English** — call `locale.setLang('zhHans')` for Chinese. ## Breaking changes ### Tiptap 3 All `@tiptap/*` packages are now v3. The most common changes for custom code: ```diff - import TableRow from '@tiptap/extension-table-row' + import { TableRow } from '@tiptap/extension-table' - import BulletList from '@tiptap/extension-bullet-list' + import { BulletList } from '@tiptap/extension-list' - import Placeholder from '@tiptap/extension-placeholder' + import { Placeholder } from '@tiptap/extensions' - editor.commands.setContent(html, false) + editor.commands.setContent(html, { emitUpdate: false }) - const pos = getPos() + const pos = getPos() + if (typeof pos !== 'number') return // getPos() can now return undefined ``` Echo Editor re-exports `TableRow`, `TableCell`, `TableHeader` and `TableCellBackground` for convenience. ### tippy.js → Floating UI `tippy.js` was removed. Every popup (bubble menus, slash menu, drag handle) now uses [Floating UI](https://floating-ui.com). If you imported the internal `DragHandlePlugin`, rename `tippyOptions` to `computePositionConfig`: ```diff DragHandlePlugin({ editor, element, - tippyOptions: { placement: 'left-start' }, + computePositionConfig: { placement: 'left-start' }, }) ``` ### Build output | 0.x | 1.x | | --- | --- | | `lib/echo-editor.es.js` | `lib/echo-editor.js` | | `lib/echo-editor.umd.js` | `lib/echo-editor.cjs` (UMD removed, like Tiptap 3) | | Tiptap bundled inside | Tiptap installed as a dependency and shared with your app | Imports through the package name (`import … from 'vue-echo-editor'`) are unaffected. ### Default language The default language changed from `zhHans` to `en`, and `locale.setLang()` is now **async** because additional languages are lazy-loaded: ```ts import { locale } from 'vue-echo-editor' await locale.setLang('zhHans') ``` ### Per-editor UI state Fullscreen, preview, source-code, AI-menu and other UI state used to be global, so two editors on one page affected each other. It is now per editor. If you called `useTiptapStore()` outside a component, pass the editor: ```diff - const { toggleFullscreen } = useTiptapStore() + const { toggleFullscreen } = useTiptapStore(editor) ``` ### History `History` is now built on Tiptap's `UndoRedo` extension (still named `history`, also exported as `UndoRedo`). The default `depth` increased from 10 to 100. ### Icons Icons moved from `lucide-vue-next` to its successor `@lucide/vue`. This only matters if you passed Lucide components to custom buttons. ## Fixed in 1.0 These worked incorrectly in 0.x and may change behaviour you relied on: - `@enter` never fired — it now does (Shift+Enter still inserts a new line). - Ordered list styles (roman, latin …) were lost when loading HTML. - Popover toolbar buttons rendered a `