Skip to content

noVueUndeclaredDirectives (HTML)

Language HTML
biome.json
{
"linter": {
"rules": {
"nursery": {
"noVueUndeclaredDirectives": "error"
}
}
}
}

Disallow custom Vue directives that are not declared.

Vue resolves a custom directive such as v-highlight at runtime. When nothing registers it, Vue logs a warning and the element silently loses the behavior the directive was supposed to add.

A custom directive is considered declared when any of the following registers it:

  • a top-level <script setup> binding named after the directive, using the camelCase form prefixed with v, such as vHighlight for v-highlight;
  • the component’s directives option, written either in export default, in defineComponent(...), or in defineOptions(...);
  • the rule’s globals option, which is how a directive registered globally with app.directive(...) is declared to Biome.

Built-in directives such as v-if are never reported. Nothing is reported either when the component’s options cannot be resolved statically, which happens when they use extends, mixins, a spread, or a default export that is not an object literal, or when a <script> block uses src="..." to load its content from another file.

<template>
<div v-highlight></div>
</template>
code-block.vue:2:10 lint/nursery/noVueUndeclaredDirectives ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✖ The custom directive v-highlight is undeclared.

1 │ <template>
> 2 │ <div v-highlight></div>
│ ^^^^^^^^^^^
3 │ </template>
4 │

ℹ Declare vHighlight in <script setup>, register the directive in the component's directives option, or list it in the rule's globals option.

ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.

A <script setup> binding declares the directive:

<script setup>
const vHighlight = {};
</script>
<template><div v-highlight></div></template>

So does the component’s directives option:

<script>
export default {
directives: { highlight: {} },
};
</script>
<template><div v-highlight></div></template>

A list of directive names that are registered globally with app.directive(...). Write each name in kebab-case, exactly as it appears in the template without the v- prefix: click-outside for v-click-outside. Other spellings such as clickOutside or vClickOutside do not match.

Default: []

biome.json
{
"linter": {
"rules": {
"nursery": {
"noVueUndeclaredDirectives": {
"level": "on",
"options": {
"globals": [
"click-outside"
]
}
}
}
}
}
}
<template>
<div v-click-outside></div>
</template>