Skip to content

useVueConsistentEventHyphenation (HTML)

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

Enforce a consistent hyphenation style for event names in v-on directives on custom components.

Vue converts event names between camelCase and kebab-case automatically, so @custom-event and @customEvent both listen to an event emitted as customEvent. Mixing both styles makes templates harder to read and search. The Vue documentation recommends kebab-cased event listeners in templates.

The rule only checks components, such as <MyComponent>, <my-component> and <Foo.Bar>. Native elements such as <div> are ignored, even when they have an is attribute. Dynamic event names, such as @[event], are ignored as well.

The fix is unsafe: Vue doesn’t convert event names on custom elements (web components) declared with isCustomElement, so renaming their event listeners can stop them from receiving events.

<template>
<MyComponent @customEvent="handleEvent" />
</template>
code-block.vue:2:17 lint/nursery/useVueConsistentEventHyphenation  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━

ℹ The event name customEvent isn't hyphenated.

1 │ <template>
> 2 │ <MyComponent @customEvent="handleEvent" />
│ ^^^^^^^^^^^
3 │ </template>
4 │

ℹ Vue matches event listeners regardless of their casing, so mixing camelCase and kebab-case event names makes templates inconsistent.

ℹ This project requires hyphenated (kebab-case) event names.

ℹ 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.

ℹ Unsafe fix: Rename the event to custom-event.

1 1 │ <template>
2 │ - ··<MyComponent·@customEvent="handleEvent"·/>
2 │ + ··<MyComponent·@custom-event="handleEvent"·/>
3 3 │ </template>
4 4 │

<template>
<MyComponent v-on:update:modelValue="handleEvent" />
</template>
code-block.vue:2:21 lint/nursery/useVueConsistentEventHyphenation  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━

ℹ The event name update:modelValue isn't hyphenated.

1 │ <template>
> 2 │ <MyComponent v-on:update:modelValue="handleEvent" />
│ ^^^^^^^^^^^^^^^^^
3 │ </template>
4 │

ℹ Vue matches event listeners regardless of their casing, so mixing camelCase and kebab-case event names makes templates inconsistent.

ℹ This project requires hyphenated (kebab-case) event names.

ℹ 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.

ℹ Unsafe fix: Rename the event to update:model-value.

1 1 │ <template>
2 │ - ··<MyComponent·v-on:update:modelValue="handleEvent"·/>
2 │ + ··<MyComponent·v-on:update:model-value="handleEvent"·/>
3 3 │ </template>
4 4 │

<template>
<MyComponent @custom-event="handleEvent" />
<MyComponent v-on:update:model-value="handleEvent" />
<div @customEvent="handleEvent" />
</template>

Whether event names must be hyphenated ("always") or must not contain hyphens ("never").

Default: "always"

biome.json
{
"linter": {
"rules": {
"nursery": {
"useVueConsistentEventHyphenation": {
"level": "on",
"options": {
"hyphenation": "never"
}
}
}
}
}
}
<template>
<MyComponent @custom-event="handleEvent" />
</template>
code-block.vue:2:17 lint/nursery/useVueConsistentEventHyphenation  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━

ℹ The event name custom-event contains hyphens.

1 │ <template>
> 2 │ <MyComponent @custom-event="handleEvent" />
│ ^^^^^^^^^^^^
3 │ </template>
4 │

ℹ Vue matches event listeners regardless of their casing, so mixing camelCase and kebab-case event names makes templates inconsistent.

ℹ This project requires event names without hyphens, such as camelCase.

ℹ 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.

ℹ Unsafe fix: Rename the event to customEvent.

1 1 │ <template>
2 │ - ··<MyComponent·@custom-event="handleEvent"·/>
2 │ + ··<MyComponent·@customEvent="handleEvent"·/>
3 3 │ </template>
4 4 │

<template>
<MyComponent @customEvent="handleEvent" />
</template>

A list of event names that aren’t checked.

Default: []

biome.json
{
"linter": {
"rules": {
"nursery": {
"useVueConsistentEventHyphenation": {
"level": "on",
"options": {
"ignore": [
"customEvent"
]
}
}
}
}
}
}
<template>
<MyComponent @customEvent="handleEvent" />
</template>

A list of tag names whose events aren’t checked. Tag names are matched exactly.

Default: []

biome.json
{
"linter": {
"rules": {
"nursery": {
"useVueConsistentEventHyphenation": {
"level": "on",
"options": {
"ignoreTags": [
"MyComponent"
]
}
}
}
}
}
}
<template>
<MyComponent @customEvent="handleEvent" />
</template>