Skip to content

noVueLoneTemplate (HTML)

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

Disallow <template> elements in a Vue template that don’t use v-if, v-else-if, v-else, v-for, or v-slot.

Inside a Vue template, a <template> element is an invisible wrapper only when it has one of these directives. Without one, Vue renders it as a regular HTML <template> element, and the browser doesn’t show its content on the page.

The <template> at the top level of a .vue file isn’t checked.

<template>
<template>
<p>Hello</p>
</template>
</template>
code-block.vue:2:3 lint/nursery/noVueLoneTemplate ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✖ This <template> has no v-if, v-else-if, v-else, v-for, or v-slot directive.

1 │ <template>
> 2 │ <template>
│ ^^^^^^^^^^
3 │ <p>Hello</p>
4 │ </template>

ℹ Without one of these directives, Vue renders a regular HTML <template> element, and the browser doesn't show its content.

ℹ Add the directive you meant to use, or remove the <template> tags and keep their content.

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

<template>
<template class="greeting">
<p>Hello</p>
</template>
</template>
code-block.vue:2:3 lint/nursery/noVueLoneTemplate ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✖ This <template> has no v-if, v-else-if, v-else, v-for, or v-slot directive.

1 │ <template>
> 2 │ <template class="greeting">
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
3 │ <p>Hello</p>
4 │ </template>

ℹ Without one of these directives, Vue renders a regular HTML <template> element, and the browser doesn't show its content.

ℹ Add the directive you meant to use, or remove the <template> tags and keep their content.

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

<template>
<template v-if="visible">
<p>Hello</p>
</template>
<template v-else>
<p>Goodbye</p>
</template>
<template v-for="item in items">
<p>{{ item }}</p>
</template>
<MyList>
<template #item>
<p>Item</p>
</template>
</MyList>
</template>

Default: false

When true, a <template> without one of these directives is allowed if it has an id or ref attribute, written plainly or bound with v-bind. Use this when your code reads the <template> element on purpose, for example to copy its content.

biome.json
{
"linter": {
"rules": {
"nursery": {
"noVueLoneTemplate": {
"level": "on",
"options": {
"ignoreAccessible": true
}
}
}
}
}
}
<template>
<template class="row">
<p>Cell</p>
</template>
</template>
code-block.vue:2:3 lint/nursery/noVueLoneTemplate ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✖ This <template> has no v-if, v-else-if, v-else, v-for, or v-slot directive.

1 │ <template>
> 2 │ <template class="row">
│ ^^^^^^^^^^^^^^^^^^^^^^
3 │ <p>Cell</p>
4 │ </template>

ℹ Without one of these directives, Vue renders a regular HTML <template> element, and the browser doesn't show its content.

ℹ Add the directive you meant to use, or remove the <template> tags and keep their content.

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

<template>
<template id="row">
<p>Cell</p>
</template>
<template ref="rowTemplate">
<p>Cell</p>
</template>
</template>