Avoiding unnecessary divs with NuxtUI and Nuxt/eslint?
I feel like I can't get rid of an unnecessary <div> when adhearing to the eslint rules, which disallow multiple root elements in a <template> tag.
Is there any way to do this correctly so to adhear to the nuxt/eslint module rules?
App.vue
defaul.vue (in layouts folder)
index.vue --> here lies the problem: I have to wrap everything with a div, which is not needed since the u-containers go into the <main> of default.vue from layouts. I can also not simply move the <UMain> in here instead of the <div>, since then default.vue will complain, since
<slot> cannot be a root element.
8 Replies
Hi @fTxUser. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
You're correct that Nuxt (and Vue) require a single root element in each template, which is enforced by both the framework and ESLint rules. This often leads to wrapping content in an extra
<div>
, which can feel unnecessary, especially when using layout components like <UMain>
and <UContainer>
from Nuxt UI.
Why the extra <div>
is needed
- Vue/Nuxt single root requirement: Every .vue
file's <template>
must have a single root element. This is a core Vue rule, not just an ESLint preference.
- Layouts and slots: In your setup, the layout's <UMain><slot /></UMain>
expects the slot content (your page) to be a single node. If you have multiple <UContainer>
s at the root of your page, you must wrap them.
Alternatives and Best Practices
- Fragment syntax: Vue 3 supports fragments (multiple root nodes), but Nuxt's layout system still expects a single root element for slot content, and ESLint rules may enforce this for consistency and compatibility.
- Avoiding unnecessary <div>
s: You can use a semantic element (like <section>
, <article>
, etc.) or a <template>
tag with v-if
/v-for
in some cases, but for static content, a wrapper is still required.
Example (as you have it)
This is the correct and recommended approach given the current Nuxt and Vue constraints. There is no built-in way in Nuxt or Nuxt UI to avoid this wrapper while still adhering to the single root requirement and ESLint rules Layouts in Nuxt 3.
Summary
- The extra wrapper is required by Vue/Nuxt, not just ESLint.
- You can use a semantic element instead of <div>
if it makes sense for your content.
- There is no Nuxt UI or Nuxt-specific feature to eliminate this requirement.
If future versions of Nuxt or Vue change this behavior, the documentation will reflect it, but as of now, your approach is correct and idiomatic.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@405922071395434496> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai is this eslint rule maybe just for vue2 support and can be savely disabled when using vue3?
Let me check the knowledge base for you again. One moment! :books:
----------------------
The requirement for a single root element in Vue components is not just an ESLint rule for Vue 2 support—it is a core part of Vue's design, and still applies in Vue 3 and Nuxt 3/4. While Vue 3 itself supports fragments (multiple root nodes in a component), Nuxt's page and layout system still expects a single root element for each page and layout slot. This is enforced both by the framework and by ESLint rules for consistency and compatibility Vue with Nuxt pages directory.
Disabling this ESLint rule would not change the underlying requirement in Nuxt: your pages and layouts must still have a single root element to work correctly, especially for features like route transitions. So, it is not just for Vue 2 support, and disabling it is not recommended when using Nuxt 3 or 4.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------
<@405922071395434496> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai but if my layout has a single root element and my pages have multiple and my pages go inside the layout, isn't the requirement fullfilt?
So Vue 3 allows multiple root elements in a component (https://v3-migration.vuejs.org/new/fragments), In Nuxt 3/4 however, layout and page components need to have a single root element (https://nuxt.com/docs/4.x/guide/directory-structure/app/layouts, https://nuxt.com/docs/4.x/guide/directory-structure/app/pages).
If using the
@nuxt/eslint
module, this won't raise errors on normal components but will raise an error in a layout and page components, if they have multiple root elements.
Secondly, ESLint doesn't know where your component fits in to the tree, it just runs it checks on a file by file basis.@TheFlyer1983 exactly, so when I remove the redundant wrapper div on the Index page - eslint will complain, so I am forced to have this unnecessary div in my html tree. Not that it‘s a big issue, but it seems semantically unnecessary and therefor wrong to my ocd brain hehe