If you are reading this blog post, chances are that you have encountered the above error and have no idea what it is and how to solve it.

Luckily for you, I went through the pain and investigation so you do not have to. In this article, I am going to explain why the error is happening and how to solve it. If you just want the solution please jump to the “Solution” paragraph at the end of this article.

TLTR: You have to set inheritAttrs=false in the child component options and also decide where the attributes should be assigned adding v-bind="$attrs" to the element of choice.

Why is this warning triggered?

The error is triggered by Vue not being able to pass attributes to the child component as it includes more than one root element (there are some special cases listed below too!). Attributes can be Id, class, style, click, or anything that we may pass to a component that is not a defined property.

These attributes are usually handled by Vue and passed through the child component without warning, but in some cases, Vue Js is not able to do so and will trigger the “extraneous non-props attributes” warning.

The following diagram shows a normal attribute flow where the parents pass some attributes to the child.

The above example has no issues because the framework is able to pass the attribute correctly to the child ROOT element which in our case is a button element.

The problem arises when our child-element has more than one component in its root. As you probably know this was not possible in Vue 2, but in Vue 3 with the introduction of fragments we are able to have more than one element in the root and this makes attributes fallthrough more complicated.

let’s see another example:

In this new example Vue is not able to pass the attribute over as it is not able to decide where to assign them (and this is done by design as assigning it to all the elements would be a mistake).

Edge Cases

Before we move forward I want to provide a couple of edge cases that will actually trigger this issue that is somewhat unexpected (or not clearly visible in plain sight):

  1. Comments count as elements in the root (unless removed in the Production build).
  2. <Transition> is NOT an actual element. So if you add two-element within a transition it will trigger the above issue (NOTE: you are not allowed to have 2 elements in a transition anyway)
  3. Likewise, <Teleport> is NOT an actual element. If you add two elements within a teleport, it will trigger the error.

Solution

The solution is pretty simple and explained in the official documentation for Fallthrough Attributes, all we need to do is manually define how the attribute is handled.

This can be achieved with 2 steps.

  • Inform Vue that we will handle attributes manually
  • Define which element will handle the attribute

The first point is done easily with the use of “inheritAttrs” and setting it to false.

<template>
  <label>
    Click me if you dare
  </label>
  <input type="text" />
</template>

<script>
export default {
  inheritAttrs: false
}
</script>

NOTE: There is no script setup syntax and you will have to add a standalone script as shown above in your component if you are using the script setup.

<script>
export default {
  inheritAttrs: false
}
</script>
<script setup>
... your component logic
</script>

Now it is time to tell Vue where to assign our attributes. We can do this using the v-bind="$attrs". We are actually able to split the attribute into different elements, but for the scope of this article, we are just going to pass through all the attributes directly.

<template>
  <label>
    Click me if you dare
  </label>
  <input type="text" v-bind="$attrs" />
</template>

<script>
export default {
  inheritAttrs: false
}
</script>

In the above example, all attributes are now passed over to the input element and the warning will be removed. If we go back to our example above, the HTML output will be as follow

Conclusion

I hope the above solution and explanation will help you save some time and please feel free to leave a comment below if you find any other use case for this warning that is not covered above so that I can update it to help other readers.

🤞 Don’t miss these tips!

No spam emails.. Pinky promise!