nuxt-tiptap-editor
v3.4.0
Published
Essentials to Quickly Integrate TipTap Editor into your Nuxt App
Maintainers
Readme
Quick Setup
Add
nuxt-tiptap-editordependency to your projectnpx nuxi@latest module add tiptapAdd
nuxt-tiptap-editorto themodulessection ofnuxt.config.tsexport default defineNuxtConfig({ modules: ['nuxt-tiptap-editor'], tiptap: { prefix: 'Tiptap', //prefix for Tiptap imports, composables not included }, });You can use the contents of this file as reference.
Copy the code to your owncomponents/TiptapEditor.vue.
Any path is fine as long as it's undercomponentsdirectory with.vueextension.<template> <div> <div v-if="editor"> <button @click="editor.chain().focus().toggleBold().run()" :disabled="!editor.can().chain().focus().toggleBold().run()" :class="{ 'is-active': editor.isActive('bold') }" > bold </button> <button @click="editor.chain().focus().toggleItalic().run()" :disabled="!editor.can().chain().focus().toggleItalic().run()" :class="{ 'is-active': editor.isActive('italic') }" > italic </button> <button @click="editor.chain().focus().toggleStrike().run()" :disabled="!editor.can().chain().focus().toggleStrike().run()" :class="{ 'is-active': editor.isActive('strike') }" > strike </button> <button @click="editor.chain().focus().toggleCode().run()" :disabled="!editor.can().chain().focus().toggleCode().run()" :class="{ 'is-active': editor.isActive('code') }" > code </button> <button @click="editor.chain().focus().unsetAllMarks().run()"> clear marks </button> <button @click="editor.chain().focus().clearNodes().run()"> clear nodes </button> <button @click="editor.chain().focus().setParagraph().run()" :class="{ 'is-active': editor.isActive('paragraph') }" > paragraph </button> <button @click="editor.chain().focus().toggleHeading({ level: 1 }).run()" :class="{ 'is-active': editor.isActive('heading', { level: 1 }) }" > h1 </button> <button @click="editor.chain().focus().toggleHeading({ level: 2 }).run()" :class="{ 'is-active': editor.isActive('heading', { level: 2 }) }" > h2 </button> <button @click="editor.chain().focus().toggleHeading({ level: 3 }).run()" :class="{ 'is-active': editor.isActive('heading', { level: 3 }) }" > h3 </button> <button @click="editor.chain().focus().toggleHeading({ level: 4 }).run()" :class="{ 'is-active': editor.isActive('heading', { level: 4 }) }" > h4 </button> <button @click="editor.chain().focus().toggleHeading({ level: 5 }).run()" :class="{ 'is-active': editor.isActive('heading', { level: 5 }) }" > h5 </button> <button @click="editor.chain().focus().toggleHeading({ level: 6 }).run()" :class="{ 'is-active': editor.isActive('heading', { level: 6 }) }" > h6 </button> <button @click="editor.chain().focus().toggleBulletList().run()" :class="{ 'is-active': editor.isActive('bulletList') }" > bullet list </button> <button @click="editor.chain().focus().toggleOrderedList().run()" :class="{ 'is-active': editor.isActive('orderedList') }" > ordered list </button> <button @click="editor.chain().focus().toggleCodeBlock().run()" :class="{ 'is-active': editor.isActive('codeBlock') }" > code block </button> <button @click="editor.chain().focus().toggleBlockquote().run()" :class="{ 'is-active': editor.isActive('blockquote') }" > blockquote </button> <button @click="editor.chain().focus().setHorizontalRule().run()"> horizontal rule </button> <button @click="editor.chain().focus().setHardBreak().run()"> hard break </button> <button @click="editor.chain().focus().undo().run()" :disabled="!editor.can().chain().focus().undo().run()" > undo </button> <button @click="editor.chain().focus().redo().run()" :disabled="!editor.can().chain().focus().redo().run()" > redo </button> </div> <TiptapEditorContent :editor="editor" /> </div> </template> <script setup> const editor = useEditor({ content: "<p>I'm running Tiptap with Vue.js. 🎉</p>", extensions: [TiptapStarterKit], }); // TipTap 3 cleans up automatically when the component unmounts; // no manual editor.destroy() call is needed. </script>Now edit the HTML, replace
buttonwith your UI provided component, or style it using tailwind or whichever CSS you are using, add icons or text, modify active state class, verify dark mode, etc.
That's it! You can now use Nuxt TipTap Editor in your Nuxt app ✨
Development
This repo uses pnpm as the package manager.
# Install dependencies
pnpm install
# Generate type stubs (must be run after install and after structural changes in src/)
pnpm dev:prepare
# Develop with the playground
pnpm dev
# Build the playground
pnpm build
# Run ESLint
pnpm lint
# Run Vitest (also runs vue-tsc --noEmit)
pnpm test
pnpm test:watchReleasing
Use the version-bump scripts (they trigger CI publish via OIDC):
pnpm release:patch # 3.2.x → 3.2.(x+1)
pnpm release:minor # 3.2.x → 3.3.0
pnpm release:major # 3.x.y → 4.0.0See RELEASE.md for details.
Upgrading TipTap or Nuxt
After bumping a major dependency, run the full suite — pnpm test and pnpm test:types will catch:
- removed/renamed module APIs (registration tests)
- broken extension behavior (command tests)
- broken auto-import wiring (registration tests + smoke tests)
- broken lowlight head-link injection
Things the test suite cannot catch — please verify manually in pnpm dev:
- BubbleMenu / FloatingMenu rendering and positioning
- Drag/drop and paste flows in
playground/components/TipTapImage.vue - Visual / CSS regressions
Contribution
Feel free to send out any valid pull requests. Would love to get any help!
