Skip to Content
LearnCustomizationNodes

Custom Nodes

A powerful feature of Vue Flow is the ability to create custom nodes. This gives you the flexibility to render anything you want within your nodes. We generally recommend creating your own custom nodes rather than relying on built-in ones. With custom nodes, you can add as many source and target handles as you like—or even embed form inputs, charts, and other interactive elements.

In this section, we’ll walk through creating a custom node featuring an input field that updates text elsewhere in your application. For further examples, we recommend checking out our Custom Node Example.

Implementing a Custom Node

To create a custom node, all you need to do is create a Vue component. Vue Flow will automatically wrap it in an interactive container that injects essential props like the node’s id, position, and data, and provides functionality for selection, dragging, and connecting handles. For a full reference on all available custom node props, take a look at the Node Props.

Let’s dive into an example by creating a custom node called TextUpdaterNode. For this, we’ve added an input field with an input handler. We use the text property from the node’s data for the input and update the node’s data via the updateNodeData function, which can be accessed through the useVueFlow composable.

TextUpdaterNode.vue
<script setup lang="ts"> import type { NodeProps } from '@xyflow/vue'; import { useVueFlow } from '@xyflow/vue'; const props = defineProps<NodeProps>(); const { updateNodeData } = useVueFlow(); function onInput(event: Event) { updateNodeData(props.id, { text: (event.target as HTMLInputElement).value }); } </script> <template> <div class="text-updater-node"> <div> <label for="text">Text:</label> <input id="text" name="text" class="nodrag" :value="data.text" @input="onInput" /> </div> </div> </template>

Adding the Node Type

Now we need to tell Vue Flow how to render our new node type. Vue Flow maps a node’s type to a named slot  of the form #node-<type> on the <VueFlow /> component. Add a #node-textUpdater slot and render your component, forwarding the slot props with v-bind:

App.vue
<script setup lang="ts"> import { VueFlow } from '@xyflow/vue'; import TextUpdaterNode from './TextUpdaterNode.vue'; // [...] </script> <template> <VueFlow v-model:nodes="nodes" v-model:edges="edges" fit-view> <template #node-textUpdater="props"> <TextUpdaterNode v-bind="props" /> </template> </VueFlow> </template>

Prefer registering by object? Vue Flow also accepts a nodeTypes prop as an alternative to the #node-<type> slots.

After defining your new node type, you can refer to it by using the type node option:

const nodes = shallowRef([ { id: 'node-1', type: 'textUpdater', position: { x: 0, y: 0 }, data: { text: 'some text' }, }, ]);

After putting it all together and adding some basic styles we get a custom node that lets you update the node text in real time:

To enable your custom node to connect with other nodes, check out the Handles page to learn how to add source and target handles.

Last updated on