Skip to Content
ExamplesEdges

Custom Edges

React Flow comes with four different edge types - default (bezier), straight, step and smoothstep. It’s also possible to create a custom edge, if you need special edge routing or controls at the edge. In this example we are demonstrating how to implement an edge with a button, a bi-directional edge, a self connecting edge. In all examples we are using the BaseEdge component as a helper.

import React, { useCallback } from 'react'; import { ReactFlow, useNodesState, useEdgesState, addEdge, Controls, Background, Position, ConnectionMode, MarkerType, type OnConnect, type Node, type Edge, } from '@xyflow/react'; import '@xyflow/react/dist/style.css'; import ButtonEdge from './ButtonEdge'; import SelfConnectingEdge from './SelfConnectingEdge'; import BiDirectionalEdge from './BiDirectionalEdge'; import BiDirectionalNode from './BiDirectionalNode'; const initialNodes: Node[] = [ { id: 'button-1', type: 'input', data: { label: 'Button Edge 1' }, position: { x: 125, y: 0 }, }, { id: 'button-2', data: { label: 'Button Edge 2' }, position: { x: 125, y: 200 }, }, { id: 'bi-1', data: { label: 'Bi Directional 1' }, position: { x: 0, y: 300 }, type: 'bidirectional', sourcePosition: Position.Right, targetPosition: Position.Left, }, { id: 'bi-2', data: { label: 'Bi Directional 2' }, position: { x: 250, y: 300 }, type: 'bidirectional', sourcePosition: Position.Right, targetPosition: Position.Left, }, { id: 'self-1', data: { label: 'Self Connecting' }, position: { x: 125, y: 500 }, sourcePosition: Position.Right, targetPosition: Position.Left, }, ]; const initialEdges: Edge[] = [ { id: 'edge-button', source: 'button-1', target: 'button-2', type: 'buttonedge', }, { id: 'edge-bi-1', source: 'bi-1', target: 'bi-2', type: 'bidirectional', sourceHandle: 'right', targetHandle: 'left', markerEnd: { type: MarkerType.ArrowClosed }, }, { id: 'edge-bi-2', source: 'bi-2', target: 'bi-1', type: 'bidirectional', sourceHandle: 'left', targetHandle: 'right', markerEnd: { type: MarkerType.ArrowClosed }, }, { id: 'edge-self', source: 'self-1', target: 'self-1', type: 'selfconnecting', markerEnd: { type: MarkerType.Arrow }, }, ]; const edgeTypes = { bidirectional: BiDirectionalEdge, selfconnecting: SelfConnectingEdge, buttonedge: ButtonEdge, }; const nodeTypes = { bidirectional: BiDirectionalNode, }; const EdgesFlow = () => { const [nodes, , onNodesChange] = useNodesState(initialNodes); const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges); const onConnect: OnConnect = useCallback( (params) => setEdges((eds) => addEdge(params, eds)), [], ); return ( <ReactFlow nodes={nodes} edges={edges} onNodesChange={onNodesChange} onEdgesChange={onEdgesChange} onConnect={onConnect} snapToGrid={true} edgeTypes={edgeTypes} nodeTypes={nodeTypes} fitView attributionPosition="top-right" connectionMode={ConnectionMode.Loose} style={{ backgroundColor: "#F7F9FB" }} > <Controls /> <Background /> </ReactFlow> ); }; export default EdgesFlow;
Last updated on