Accessibility
If you have suggestions for how we can improve the accessibility of Vue Flow, please contact us .
Vue Flow provides keyboard and screen-reader support to help meet accessibility standards. By
default, all nodes and edges are keyboard-focusable and operable. You can toggle these features
with props such as nodesFocusable,
edgesFocusable, and
disableKeyboardA11y, passed to <VueFlow>:
<script setup lang="ts">
import { VueFlow } from '@xyflow/vue';
import '@xyflow/vue/style.css';
</script>
<template>
<VueFlow
v-model:nodes="nodes"
v-model:edges="edges"
:nodes-focusable="true"
:edges-focusable="true"
:disable-keyboard-a11y="false"
>
<!-- ...other components like Controls, MiniMap... -->
</VueFlow>
</template>Built-in features
- Tab navigation: Pressing
Tabmoves focus through all focusable nodes and edges. These elements receivetabindex="0"and, by default,role="group". - Select / deselect: Press
EnterorSpaceto select the focused node or edge, andEscapeto clear the selection. - Move nodes with arrow keys: If
nodesDraggableandnodesFocusableare both true (the default), you can move the selected node with the arrow keys. HoldShiftto move faster. Setting:disable-keyboard-a11y="true"disables arrow-key movement, while tab-focus and selection still work. - Automatic panning: When a node receives focus, Vue Flow pans the canvas to bring it into
view. Toggle this with the
autoPanOnNodeFocusprop. - ARIA descriptions: Vue Flow adds ARIA descriptions for keyboard guidance, configurable
through
ariaLabelConfig.
For full keyboard accessibility, keep both nodesFocusable and edgesFocusable set to
true. If either is false, those elements won’t be keyboard-focusable.
ARIA roles for nodes and edges
By default Vue Flow uses semantic ARIA roles for interactive elements. Override a node’s role
with the ariaRole field:
const nodes = [
{ id: '1', position: { x: 0, y: 0 }, data: { label: 'Hello' }, ariaRole: 'button' },
];If you don’t set a role, role="group" is applied. Customizing ariaRole lets you match any
relevant role ('listitem', 'region', and so on), improving the semantics for assistive
technology.
ariaRole is applied to the node wrapper. If a custom node contains interactive elements,
don’t set ariaRole: 'button' on the node itself. Apply the appropriate role directly to the
interactive element inside.
DOM attributes
To pass custom ARIA or other DOM-level attributes (aria-roledescription, data-*, tabindex,
and so on), use the domAttributes field. It’s available on both nodes and edges:
const nodes = [
{
id: '2',
position: { x: 0, y: 100 },
data: { label: 'Accessible Node' },
domAttributes: {
'aria-roledescription': 'collapsible node',
'data-test-id': 'node-2',
},
},
];This gives you full control over accessibility-related attributes while keeping Vue Flow’s built-in roles and behavior.
Localizing accessibility messages
Vue Flow’s built-in accessibility text (keyboard instructions and live updates) can be
customized or localized with the ariaLabelConfig
prop, an object mapping message keys to strings (or functions). The keys are:
| Key | Default value |
|---|---|
node.a11yDescription.default | Press enter or space to select a node. Press delete to remove it and escape to cancel. |
node.a11yDescription.keyboardDisabled | Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel. |
node.a11yDescription.ariaLiveMessage | Moved selected node {direction}. New position, x: {x}, y: {y} |
edge.a11yDescription.default | Press enter or space to select an edge. You can then press delete to remove it or escape to cancel. |
controls.ariaLabel | Control Panel |
controls.zoomIn.ariaLabel | Zoom In |
controls.zoomOut.ariaLabel | Zoom Out |
controls.fitView.ariaLabel | Fit View |
controls.interactive.ariaLabel | Toggle Interactivity |
minimap.ariaLabel | Mini Map |
handle.ariaLabel | Handle |
For example, to localize the node instructions:
<script setup lang="ts">
import { Controls, MiniMap, VueFlow } from '@xyflow/vue';
const ariaLabelConfig = {
'node.a11yDescription.default': 'Press [Enter] to select this node',
'node.a11yDescription.keyboardDisabled': 'Keyboard navigation is disabled',
};
</script>
<template>
<VueFlow v-model:nodes="nodes" v-model:edges="edges" :aria-label-config="ariaLabelConfig">
<MiniMap />
<Controls />
</VueFlow>
</template>Vue Flow then uses your text instead of the defaults, so screen readers announce messages in the user’s language.
WCAG 2.1 AA
Vue Flow provides features that help you meet key WCAG 2.1 AA criteria when implemented properly:
- Keyboard:
Tabnavigation to nodes and edges, interaction withEnter/Space, and arrow-key movement for nodes support keyboard operability. - Screen reader: Semantic ARIA roles and labels (
role="group",aria-label,aria-roledescription) let assistive technology announce nodes and edges meaningfully. - ARIA live regions: Dynamic updates are announced through an
aria-live="assertive"region that reports node movements. - Instructions and focus management: Contextual instructions (“Press enter or space to select a node…”) plus automatic panning-into-view on focus help satisfy input-assistance requirements.
See the ARIA authoring practices for background on ARIA best practices.