Nuxt
This guide covers how to integrate Tiptap with your Nuxt 4 project, complete with code examples.
Requirements
Create a project (optional)
If you already have a Nuxt project, that's fine too. Just skip this step.
For the purpose of this guide, start with a fresh Nuxt project called my-tiptap-project. The following command sets up everything you need:
# create a project
npx nuxi@latest init my-tiptap-project
# change directory
cd my-tiptap-projectInstall the dependencies
Now let's install Tiptap! For the following example, you'll need the @tiptap/vue-3 package with a few components, the @tiptap/pm package, and @tiptap/starter-kit, which has the most common extensions to get started quickly.
npm install @tiptap/vue-3 @tiptap/pm @tiptap/starter-kitIf you followed steps 1 and 2, you can now start your project with npm run dev and open http://localhost:3000/ in your favorite browser. This might be different if you're working with an existing project.
Integrate Tiptap
To actually start using Tiptap, you'll need to add a new component to your app. Let's call it TiptapEditor and put the following example code in components/TiptapEditor.vue.
This is the fastest way to get Tiptap up and running with Vue. It will give you a very basic version of Tiptap, without any buttons. No worries, you will be able to add more functionality soon.
<template>
<EditorContent :editor="editor" />
</template>
<script setup>
import { useEditor, EditorContent } from '@tiptap/vue-3'
import StarterKit from '@tiptap/starter-kit'
const editor = useEditor({
content: `<p>I'm running Tiptap with Vue.js. 🎉</p>`,
extensions: [StarterKit],
})
</script>Add it to your app
Now, replace the content of app/app.vue with the following code to use our new TiptapEditor component:
<template>
<TiptapEditor />
</template>In Nuxt 4, both components and Vue composables (like ref and watch) are auto-imported, so you don't need to manually import or register them.
You should now see Tiptap in your browser. Time to give yourself a pat on the back! :)
Use v-model (optional)
You're probably used to binding your data with v-model in forms. This also possible with Tiptap. Here's a working example component, that you can integrate in your project:
<template>
<EditorContent :editor="editor" />
</template>
<script setup>
import { useEditor, EditorContent } from '@tiptap/vue-3'
import StarterKit from '@tiptap/starter-kit'
const emit = defineEmits(['update:modelValue'])
const props = defineProps({
modelValue: {
type: String,
default: '',
},
})
const editor = useEditor({
content: props.modelValue,
extensions: [StarterKit],
onUpdate: ({ editor }) => {
// HTML
emit('update:modelValue', editor.getHTML())
// JSON
// emit('update:modelValue', editor.getJSON())
},
})
watch(
() => props.modelValue,
(value) => {
// HTML
const isSame = editor.value?.getHTML() === value
// JSON
// const isSame = JSON.stringify(editor.value?.getJSON()) === JSON.stringify(value)
if (isSame) {
return
}
editor.value?.commands.setContent(value, false)
}
)
</script>