Handles
Handles are the connection points on nodes in Vue Flow. Our built-in nodes include one source and one target handle, but you can customize your nodes with as many different handles as you need.
Creating a node with handles
To create a custom node with handles, you can use the
<Handle /> component provided by Vue Flow. This
component allows you to define source and target handles for your custom nodes. Here’s an
example of how to implement a custom node with two handles:
<script setup lang="ts">
import { Handle, Position } from '@xyflow/vue';
</script>
<template>
<div class="custom-node">
<div>Custom Node Content</div>
<Handle type="source" :position="Position.Top" />
<Handle type="target" :position="Position.Bottom" />
</div>
</template>Using multiple handles
If you want to use multiple source or target handles in your custom node, you need to
specify each handle with a unique id. This allows Vue Flow to differentiate between
the handles when connecting edges.
<Handle type="target" :position="Position.Top" />
<Handle id="a" type="source" :position="Position.Right" />
<Handle id="b" type="source" :position="Position.Bottom" />To connect an edge to a specific handle of a node, use the properties sourceHandle (for
the edge’s starting point) and targetHandle (for the edge’s ending point). By defining
sourceHandle or targetHandle with the appropriate handle id, you instruct Vue Flow
to attach the edge to that specific handle, ensuring that connections are made where you
intend.
const edges = shallowRef([
{ id: 'n1-n2', source: 'n1', sourceHandle: 'a', target: 'n2' },
{ id: 'n1-n3', source: 'n1', sourceHandle: 'b', target: 'n3' },
]);In this case, the source node is n1 for both handles but the handle ids are different.
One comes from handle id a and the other one from b. Both edges also have different
target nodes:
By default Vue Flow positions a handle in the center of the specified side. If you want to display multiple handles on a side, you can adjust the position via inline styles or overwrite the default CSS and position it on your own.
Custom handles
You can use any custom component as a Handle by wrapping it with the
<Handle /> component. Follow these steps to
integrate your custom component:
- Wrap your custom component with the
<Handle />component. - Hide the built-in
<Handle />appearance by settingborderandbackgroundtonone. - Set the
widthandheightof<Handle />to match your custom component. - Style the child component with
pointer-events: none. - Then, reposition the child custom component using CSS position properties like
top, leftif necessary to position it perfectly inside the<Handle />component.
This example shows a custom icon used as a Handle:
<script setup lang="ts">
import { Handle, Position } from '@xyflow/vue';
</script>
<template>
<div class="vue-flow__node-default">
<Handle
type="source"
:position="Position.Right"
:style="{ background: 'none', border: 'none', width: '1em', height: '1em' }"
>
<span
style="pointer-events: none; font-size: 1em; left: 0; position: absolute;"
aria-hidden="true"
>→</span>
</Handle>
Custom Node
</div>
</template>Typeless handles
If you want to create a handle that does not have a specific type (source or target), you
can set connectionMode to ConnectionMode.Loose on the
<VueFlow /> component. This allows the handle to be used for both incoming and outgoing
connections.
<script setup lang="ts">
import { ConnectionMode, VueFlow } from '@xyflow/vue';
</script>
<template>
<VueFlow :connection-mode="ConnectionMode.Loose" />
</template>Dynamic handles
If you are programmatically changing the position or number of handles in your custom
node, you need to update the node internals with the updateNodeInternals method from
the useVueFlow composable.
Custom handle styles
Since the handle is a div, you can use CSS to style it or pass a style prop to customize a Handle. You can see this in the Add Node On Edge Drop example.
Styling handles when connecting
The handle receives the additional class names connectingfrom and connectingto when
the connection line is above the handle and valid if the connection is valid. You can
find an example which uses these classes here.
Hiding handles
If you need to hide a handle for some reason, you must use visibility: hidden or
opacity: 0 instead of display: none. This is important because Vue Flow needs to
calculate the dimensions of the handle to work properly and using display: none will
report a width and height of 0!