--- tableOfContents: true --- # Node views with Vue ## Introduction Using Vanilla JavaScript can feel complex if you are used to work in Vue. Good news: You can use regular Vue components in your node views, too. There is just a little bit you need to know, but let’s go through this one by one. ## Render a Vue component Here is what you need to do to render Vue components inside your editor: 1. [Create a node extension](/guide/custom-extensions) 2. Create a Vue component 3. Pass that component to the provided `VueNodeViewRenderer` 4. Register it with `addNodeView()` 5. [Configure Tiptap to use your new node extension](/guide/configuration) This is how your node extension could look like: ```js import { Node } from '@tiptap/core' import { VueNodeViewRenderer } from '@tiptap/vue-2' import Component from './Component.vue' export default Node.create({ // configuration … addNodeView() { return VueNodeViewRenderer(Component) }, }) ``` There is a little bit of magic required to make this work. But don’t worry, we provide a wrapper component you can use to get started easily. Don’t forget to add it to your custom Vue component, like shown below: ```html ``` Got it? Let’s see it in action. Feel free to copy the below example to get started. https://embed.tiptap.dev/preview/GuideNodeViews/VueComponent That component doesn’t interact with the editor, though. Time to wire it up. ## Access node attributes The `VueNodeViewRenderer` which you use in your node extension, passes a few very helpful props to your custom Vue component. One of them is the `node` prop. Add this snippet to your Vue component to directly access the node: ```js props: { node: { type: Object, required: true, }, }, ``` That enables you to access node attributes in your Vue component. Let’s say you have [added an attribute](/guide/custom-extensions#attributes) named `count` to your node extension (like we did in the above example) you could access it like this: ```js this.node.attrs.count ``` ## Update node attributes You can even update node attributes from your node, with the help of the `updateAttributes` prop passed to your component. Just add this snippet to your component: ```js props: { updateAttributes: { type: Function, required: true, }, }, ``` Pass an object with updated attributes to the function: ```js this.updateAttributes({ count: this.node.attrs.count + 1, }) ``` And yes, all of that is reactive, too. A pretty seemless communication, isn’t it? ## Adding a content editable There is another component called `NodeViewContent` which helps you adding editable content to your node view. Here is an example: ```html ``` You don’t need to add those `class` attributes, feel free to remove them or pass other class names. Try it out in the following example: https://embed.tiptap.dev/preview/GuideNodeViews/VueComponentContent Keep in mind that this content is rendered by Tiptap. That means you need to tell what kind of content is allowed, for example with `content: 'inline*'` in your node extension (that’s what we use in the above example). The `NodeViewWrapper` and `NodeViewContent` components render a `
` HTML tag (`` for inline nodes), but you can change that. For example `` should render a paragraph. One limitation though: That tag must not change during runtime. ## All available props For advanced use cases, we pass a few more props to the component. ### editor The editor instance. ### node Access the current node. ### decorations An array of decorations. ### selected `true` when there is a `NodeSelection` at the current node view. ### extension Access to the node extension, for example to get options. ### getPos() Get the document position of the current node. ### updateAttributes() Update attributes of the current node. ### deleteNode() Delete the current node. Here is the full list of what props you can expect: ```html ``` If you just want to have all (and TypeScript support) you can import all props like that: ```js // Vue 3 import { defineComponent } from 'vue' import { nodeViewProps } from '@tiptap/vue-3' export default defineComponent({ props: nodeViewProps, }) // Vue 2 import Vue from 'vue' import { nodeViewProps } from '@tiptap/vue-2' export default Vue.extend({ props: nodeViewProps, }) ``` ## Dragging To make your node views draggable, set `draggable: true` in the extension and add `data-drag-handle` to the DOM element that should function as the drag handle. https://embed.tiptap.dev/preview/GuideNodeViews/DragHandle