Skip to Content

Handles

Handles are the connection points on nodes in React 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 React 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:

import { Handle } from '@xyflow/react'; export function CustomNode() { return ( <div className="custom-node"> <div>Custom Node Content</div> <Handle type="source" position="top" /> <Handle type="target" position="bottom" /> </div> ); }

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 React Flow to differentiate between the handles when connecting edges.

<Handle type="target" position="top" /> <Handle type="source" position="right" id="a" /> <Handle type="source" position="bottom" id="b" />

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 React Flow to attach the edge to that specific handle, ensuring that connections are made where you intend.

const initialEdges = [ { id: 'edge-1', source: 'node-1', sourceHandle: 'a', target: 'node-2' }, { id: 'edge-2', source: 'node-1', sourceHandle: 'b', target: 'node-3' }, ];

In this case, the source node is node-1 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:

import { useCallback, useState } from 'react'; import { ReactFlow, addEdge, applyEdgeChanges, applyNodeChanges, } from '@xyflow/react'; import '@xyflow/react/dist/style.css'; import TextUpdaterNode from './TextUpdaterNode'; const rfStyle = { backgroundColor: '#B8CEFF', }; const initialNodes = [ { id: 'node-1', type: 'textUpdater', position: { x: 100, y: 0 }, data: { value: 123 }, }, { id: 'node-2', type: 'output', targetPosition: 'top', position: { x: 0, y: 200 }, data: { label: 'node 2' }, }, { id: 'node-3', type: 'output', targetPosition: 'top', position: { x: 200, y: 200 }, data: { label: 'node 3' }, }, ]; const initialEdges = [ { id: 'edge-1', source: 'node-1', target: 'node-2', sourceHandle: 'a' }, { id: 'edge-2', source: 'node-1', target: 'node-3', sourceHandle: 'b' }, ]; // we define the nodeTypes outside of the component to prevent re-renderings // you could also use useMemo inside the component const nodeTypes = { textUpdater: TextUpdaterNode }; function Flow() { const [nodes, setNodes] = useState(initialNodes); const [edges, setEdges] = useState(initialEdges); return ( <ReactFlow nodes={nodes} edges={edges} nodeTypes={nodeTypes} fitView style={rfStyle} /> ); } export default Flow;

If you are programmatically changing the position or number of handles in your custom node, you will need to use the useUpdateNodeInternals hook to properly notify React Flow of changes.

Custom handles

You can create your own custom handles by wrapping the <Handle /> component. This example shows a custom handle that only allows connections when the connection source matches a given id.

import { Handle, Position } from '@xyflow/react'; export const TargetHandleWithValidation = ({ position, source }) => ( <Handle type="target" position={position} isValidConnection={(connection) => connection.source === source} onConnect={(params) => console.log('handle onConnect', params)} style={{ background: '#fff' }} /> );

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 useUpdateNodeInternals hook.

You can find an example of how to implement a custom node with multiple handles in the custom node guide or in the custom node example.

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 and Simple Floating Edges examples.

Styling handles when connecting

The handle receives the additional class names connecting 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 React Flow needs to calculate the dimensions of the handle to work properly and using display: none will report a width and height of 0!
Last updated on