Vue 3: How to Fix 'The template root requires exactly one element' ESLint Error (eslint-plugin-vue) When Disabling Rule Doesn't Work
If you’ve worked with Vue 3 and ESLint, you’ve likely encountered the frustrating error: "The template root requires exactly one element". This error, thrown by eslint-plugin-vue, can feel confusing—especially since Vue 3 explicitly supports multi-root templates (unlike Vue 2). Even more perplexing: sometimes, attempting to disable the rule via ESLint configurations or inline comments seems to have no effect.
In this guide, we’ll demystify this error, explain why disabling the rule might fail, and provide step-by-step solutions to resolve it for good. Whether you’re a seasoned Vue developer or just getting started, this post will help you troubleshoot and fix the issue efficiently.
Table of Contents#
-
- What the Error Means
- Why ESLint (eslint-plugin-vue) Enforces This
- Vue 3’s Multi-Root Template Support
-
Why Disabling the Rule Might Fail: Common Pitfalls
- Outdated
eslint-plugin-vueVersion - Disabling the Wrong Rule Name
- Incorrect Disabling Scope (Global vs. Local)
- Conflicting ESLint Configurations
- IDE/Linter Cache Issues
- Outdated
-
Step-by-Step Solutions to Fix the Error
- Step 1: Confirm Vue 3 and
eslint-plugin-vueCompatibility - Step 2: Update
eslint-plugin-vue - Step 3: Correctly Disable the Rule in ESLint Config
- Step 4: Disable the Rule Per File or Inline
- Step 5: Resolve Conflicts in ESLint Config
- Step 6: Clear Linter Cache and Restart Your Environment
- Step 1: Confirm Vue 3 and
1. Understanding the Error#
What the Error Means#
The error "The template root requires exactly one element" is triggered by ESLint (via eslint-plugin-vue) when your Vue single-file component (SFC) template contains multiple root elements. For example:
<!-- Example: Template with multiple roots (triggers the error) -->
<template>
<h1>Hello World</h1>
<p>This is a multi-root template.</p>
</template>In Vue 2, this was invalid because templates required a single root element (e.g., a <div> wrapping all content). However, Vue 3 removes this restriction, allowing multi-root templates. So why is ESLint still complaining?
Why ESLint (eslint-plugin-vue) Enforces This#
The error stems from a specific ESLint rule in eslint-plugin-vue: vue/no-multiple-template-root. This rule was designed to enforce Vue 2’s single-root template requirement. In Vue 3 projects, if your ESLint configuration includes this rule (e.g., via plugin:vue/vue3-essential or similar presets), ESLint will flag multi-root templates as errors—even though Vue 3 supports them.
Vue 3’s Multi-Root Template Support#
Vue 3’s compiler allows templates with multiple root elements, making it easier to compose components without unnecessary wrapper divs. For example:
<!-- Valid in Vue 3 (multi-root template) -->
<template>
<header>...</header>
<main>...</main>
<footer>...</footer>
</template>The error is therefore not a Vue 3 limitation—it’s purely an ESLint rule enforcing outdated Vue 2 behavior.
2. Why Disabling the Rule Might Fail: Common Pitfalls#
If you’ve tried disabling vue/no-multiple-template-root but the error persists, you’re likely hitting one of these common pitfalls:
Pitfall 1: Outdated eslint-plugin-vue Version#
Older versions of eslint-plugin-vue (pre-v7.0.0) may use a different rule name (e.g., vue/template-root-requires-one-element) or lack support for Vue 3’s multi-root templates. If you’re using an outdated version, disabling the rule may not work as expected.
Pitfall 2: Disabling the Wrong Rule Name#
The most common mistake! The correct rule name for multi-root templates in Vue 3 is vue/no-multiple-template-root. If you tried disabling a non-existent rule (e.g., vue/template-root-requires-one-element or template-root-requires-one-element), ESLint will ignore your disable attempt.
Pitfall 3: Incorrect Disabling Scope#
ESLint rules can be disabled globally (in eslintrc), per file, or inline. If you disable the rule in the wrong scope (e.g., inline in a file but the global config still enforces it), the error will persist.
Pitfall 4: Conflicting ESLint Configurations#
If your ESLint config extends a preset that explicitly enables vue/no-multiple-template-root (e.g., plugin:vue/vue3-essential), your local rules override may be ignored if not properly configured.
Pitfall 5: IDE/Linter Cache Issues#
Sometimes, your IDE (VS Code, WebStorm, etc.) or linter server (e.g., Vite’s eslint-dev-server) caches old configurations. Even if you update your ESLint config, the cache may prevent changes from taking effect.
3. Step-by-Step Solutions to Fix the Error#
Let’s walk through actionable steps to resolve the error, starting with the most common fixes.
Step 1: Confirm Vue 3 and eslint-plugin-vue Compatibility#
First, ensure your project is using Vue 3 and a compatible eslint-plugin-vue version.
- Vue Version: Check
package.jsonfor[email protected]. eslint-plugin-vueVersion: Useeslint-plugin-vue@^8.0.0or later (supports Vue 3).
Update eslint-plugin-vue if needed:
npm install eslint-plugin-vue@latest --save-dev
# or
yarn add eslint-plugin-vue@latest --devStep 2: Correctly Disable the Rule in ESLint Config#
The most reliable fix is to disable vue/no-multiple-template-root globally in your ESLint configuration file (e.g., .eslintrc.js, .eslintrc.json).
Example: Disable in .eslintrc.js#
Open your ESLint config and add 'vue/no-multiple-template-root': 'off' to the rules section:
// .eslintrc.js
module.exports = {
root: true,
env: {
node: true,
},
extends: [
'plugin:vue/vue3-essential', // May enable the rule by default
'eslint:recommended',
],
rules: {
// Disable the multi-root template rule
'vue/no-multiple-template-root': 'off', // <-- Add this line
},
};Why This Works#
The vue3-essential preset (and others like vue3-strongly-recommended) enables vue/no-multiple-template-root by default. By explicitly setting it to 'off' in the rules section, you override the preset’s configuration.
Step 3: Disable the Rule Per File or Inline#
If you only want to allow multi-root templates in specific files (not globally), use per-file or inline disables.
Per-File Disable#
Add a comment at the top of the SFC to disable the rule for the entire file:
<!-- Disable for the entire file -->
<!-- eslint-disable vue/no-multiple-template-root -->
<template>
<h1>Hello World</h1>
<p>Multi-root template (no error here!)</p>
</template>Inline Disable#
Disable the rule only for the template block using an inline comment:
<template>
<!-- eslint-disable-next-line vue/no-multiple-template-root -->
<h1>Hello World</h1>
<p>Multi-root template (no error here!)</p>
</template>Step 4: Resolve Conflicts in ESLint Config#
If your ESLint config extends multiple presets, ensure none are re-enabling vue/no-multiple-template-root. For example:
// .eslintrc.js
module.exports = {
extends: [
'plugin:vue/vue3-essential', // Enables the rule by default
'plugin:vue/vue3-recommended', // May also enable it
],
rules: {
// Override all presets: explicitly disable the rule
'vue/no-multiple-template-root': 'off',
},
};The rules section takes precedence over extends, so this ensures the rule is disabled.
Step 5: Clear Linter Cache and Restart Your Environment#
If the error persists after updating your config, your IDE or linter server may be using a cached configuration. Try:
- Restarting your IDE: Close and reopen VS Code/WebStorm.
- Restarting the linter server: If using Vite, stop and restart the dev server (
npm run dev). - Clearing ESLint cache: Run
npx eslint --clear-cacheto clear ESLint’s cache.
4. Troubleshooting: When All Else Fails#
If the error still occurs, check these edge cases:
Double-Check the Rule Name#
Ensure you’re using the exact rule name: vue/no-multiple-template-root. Typos (e.g., vue/no-multiple-roots or vue/multiple-template-root) will cause ESLint to ignore the disable.
Inspect Extended Configurations#
Use npx eslint --print-config your-file.vue to debug your ESLint config. This command outputs the final rules applied to a file, helping you identify if vue/no-multiple-template-root is still enabled.
Test with a Minimal Reproduction#
Create a new Vue 3 project and reproduce the issue in isolation. This helps rule out project-specific conflicts (e.g., custom ESLint plugins, monorepo setups).
Check for IDE-Specific Issues#
If using VS Code with the ESLint extension:
- Ensure the extension is up to date.
- Open the ESLint output panel (View > Output > ESLint) to check for errors.
- Set
"eslint.validate": ["vue"]in.vscode/settings.jsonto ensure Vue files are validated.
5. Conclusion#
The "The template root requires exactly one element" error is a relic of Vue 2, enforced by ESLint’s vue/no-multiple-template-root rule. In Vue 3, fixing it is straightforward:
- Ensure
eslint-plugin-vueis updated to v8.0.0+. - Disable
vue/no-multiple-template-rootin your ESLint config (globally, per file, or inline). - Clear caches and restart your environment to apply changes.
By following these steps, you’ll resolve the error and leverage Vue 3’s powerful multi-root template support without ESLint interference.