Skip to content

noVueUndeclaredSlots (HTML)

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

Disallow <slot> elements whose slot isn’t declared in the component’s types.

In a Vue component written in TypeScript, the slots the component renders can be declared with types. The types describe which slots a parent component can fill, and the data each slot passes to that content. Editors and type checkers use them to check the content parent components pass in. A slot that is rendered but not declared isn’t checked at all.

Slots are declared in one of two ways:

  • with defineSlots() in <script setup>;
  • with the slots option of the component, written as Object as SlotsType<...>.

A <slot> element without a name attribute renders the slot named default.

The rule only checks components that have a <script lang="ts"> or <script lang="tsx"> block, because slots can only be declared with types. It doesn’t report a slot when its name is computed with an expression, or when the declared slots come from a type that Biome can’t read, such as an imported type or an interface that extends another one.

<script setup lang="ts">
defineSlots<{
default(props: { msg: string }): any;
}>();
</script>
<template>
<slot name="footer" />
</template>
code-block.vue:8:17 lint/nursery/noVueUndeclaredSlots ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

⚠ The slot footer isn't declared.

7 │ <template>
> 8 │ <slot name="footer" />
│ ^^^^^^
9 │ </template>
10 │

ℹ Without a declaration, the content that parent components pass to this slot isn't type checked.

ℹ Declare the slot with defineSlots() in <script setup>, or with the slots option of the component.

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

<script lang="ts">
import { defineComponent, type SlotsType } from "vue";
export default defineComponent({
slots: Object as SlotsType<{
header: { title: string };
}>,
});
</script>
<template>
<slot />
</template>
code-block.vue:12:6 lint/nursery/noVueUndeclaredSlots ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

⚠ The slot default isn't declared.

11 │ <template>
> 12 │ <slot />
│ ^^^^
13 │ </template>
14 │

ℹ Without a declaration, the content that parent components pass to this slot isn't type checked.

ℹ Declare the slot with defineSlots() in <script setup>, or with the slots option of the component.

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

<script setup lang="ts">
defineSlots<{
default(props: { msg: string }): any;
footer(props: {}): any;
}>();
</script>
<template>
<slot msg="hello" />
<slot name="footer" />
</template>