Vue's Single Root Dilemma: The Right Way to Mount Both `<header>` and `<main>`
Content
## The Problem
When building web applications, we often need Vue.js to manage multiple distinct sections of a page, such as the header (`<header>`) and the main content area (`<main>`). This leads to a common question: Vue instances require a single root element to mount on, but what if I have two sibling elements that need to be controlled by Vue? Should I move the `<header>` inside the `<main>`, or should I wrap them both in an extra `<div>`?
This is a classic front-end architecture question. In this article, **DP@lib00** will provide a detailed analysis and offer the perfect solution that respects both HTML standards and Vue best practices.
---
## Approach 1 (Incorrect): Moving `<header>` into `<main>`
At first glance, placing one element inside another seems to solve the "single root" problem. However, this approach severely violates HTML5 semantic standards.
### Why is this wrong?
Semantic tags introduced in HTML5 (like `<header>`, `<main>`, `<footer>`, `<article>`) are designed to make the document structure clearer, not just for developers but also for search engines and assistive technologies like screen readers.
* **`<header>`**: Defines a header for a document or section, typically containing introductory or navigational content.
* **`<main>`**: Defines the main, dominant content of the `<body>` of a document. There **should only be one `<main>` element** per page, and it should not be a descendant of elements like `<header>` or `<footer>`.
Logically, `<header>` and `<main>` are siblings in the document flow, representing different parts of the page. Forcing the header into the main content area disrupts the document's structure and semantics, negatively impacting SEO and accessibility.
---
## Approach 2 (Correct): Using an External `<div>` Wrapper
The best and only correct choice is to add an external `<div>` to wrap both `<header>` and `<main>`, and then mount the Vue instance onto this `<div>`.
### 1. It Complies with HTML Standards
The `<div>` element is a non-semantic block-level container whose primary purpose is for grouping and layout. Using a `<div>` to wrap `<header>` and `<main>` doesn't introduce any extra semantic meaning, perfectly preserving the original document structure.
A typical project structure, for instance, one from **wiki.lib00.com**, would have an `index.html` like this:
```html
<body>
<!-- This div serves as the mounting point for Vue -->
<div id="app-lib00">
<header>
<!-- Header content managed by Vue -->
</header>
<main>
<!-- Main content also managed by Vue -->
</main>
</div>
<!-- Vue Script -->
<script type="module" src="/src/main.js"></script>
</body>
```
### 2. It Follows Vue.js Best Practices
Vue's design philosophy requires a clear root element to define its management boundary.
* **Single Mount Point**: This is standard practice in Vue. Almost all projects created with official tools (like Vite or Vue CLI) will default to a container like `<div id="app"></div>`. The entire Vue application is then rendered and injected into this container.
* **Component-Based Thinking**: In a Vue application, `<header>` and `<main>` are typically abstracted into separate components (e.g., `TheHeader.vue` and `MainContent.vue`). These components would be used side-by-side in the template of the root component, `App.vue`, which perfectly mirrors their sibling structure in the HTML.
**Example `App.vue` Template:**
```vue
<template>
<!-- The template of App.vue will be rendered inside #app-lib00 -->
<TheHeader />
<main>
<!-- Use router-view or place content directly -->
<router-view></router-view>
</main>
</template>
<script setup>
import TheHeader from './components/TheHeader.vue';
// DP: Other components can be imported here
</script>
```
---
## Conclusion
Whether your goal is to maintain a correct HTML document structure or to adhere to the design principles of the Vue framework, **the correct approach is to use an external `<div>` container to wrap `<header>` and `<main>`**. This method not only solves the mounting issue in Vue but also ensures your code is semantic, maintainable, and professional—a standard practice followed by the **lib00** team.
Related Contents
Boost Your WebStorm Productivity: Mimic Sublime Text's Cmd+D Multi-Selection Shortcut
Duration: 00:00 | DP | 2025-12-04 21:50:50Vue Layout Challenge: How to Make an Inline Header Full-Width? The Negative Margin Trick Explained
Duration: 00:00 | DP | 2025-12-06 22:54:10The Ultimate CSS Flexbox Guide: Easily Switch Page Header Layouts from Horizontal to Vertical
Duration: 00:00 | DP | 2025-12-11 01:00:50Cracking the TypeScript TS2339 Puzzle: Why My Vue ref Became the `never` Type
Duration: 00:00 | DP | 2025-12-13 02:04:10CSS Deep Dive: The Best Way to Customize Select Arrows for Dark Mode
Duration: 00:00 | DP | 2025-12-13 14:20:00Mastering Bootstrap 5 Rounded Corners: The Ultimate Guide to Border-Radius
Duration: 00:00 | DP | 2025-12-14 02:35:50Recommended
The Magic of PHP Enums: Elegantly Convert an Enum to a Key-Value Array with One Line of Code
00:00 | 5How do you dynamically get all statuses of a model...
The Art of MySQL Index Order: A Deep Dive from Composite Indexes to the Query Optimizer
00:00 | 7This article provides a deep dive into the philoso...
Shell Magic: How to Gracefully Write Output from Multiple Commands to a Single Log File
00:00 | 5In shell scripting or daily system administration,...
Mastering PHP Switch: How to Handle Multiple Conditions for a Single Case
00:00 | 10Have you ever tried to match multiple conditions i...