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>