<EdgeLabelRenderer />
Edges are rendered as SVG paths, which makes it awkward to put interactive HTML in a
label. The <EdgeLabelRenderer /> teleports its slot content into a single HTML
container that sits above the edges, so you can render fully interactive labels (with
inputs, buttons, etc.) inside a custom edge.
<!-- CustomEdge.vue -->
<script setup lang="ts">
import { BaseEdge, EdgeLabelRenderer, getBezierPath, type EdgeProps } from '@xyflow/vue';
import { computed } from 'vue';
const props = defineProps<EdgeProps>();
const path = computed(() => getBezierPath(props));
</script>
<template>
<BaseEdge :id="id" :path="path[0]" />
<EdgeLabelRenderer>
<div
:style="{
position: 'absolute',
transform: `translate(-50%, -50%) translate(${path[1]}px, ${path[2]}px)`,
pointerEvents: 'all',
}"
class="nodrag nopan"
>
<button @click="onEdgeClick">delete</button>
</div>
</EdgeLabelRenderer>
</template>Notes
<EdgeLabelRenderer />renders its default slot and takes no props.- Because the labels are absolutely positioned in one container, position each label
yourself with a
transform(see the example above), and add thenodrag nopanclasses so interacting with the label doesn’t pan the pane. - This is the Vue Flow equivalent of rendering into the viewport layer — for
non-label content anchored to the transformed pane, use the
#zoom-paneslot on<VueFlow />instead.
Last updated on