HTML Document Structure
Skeleton of a solid HTML document — doctype, html/lang, head metadata, body landmarks, and what belongs where.
- html
- document-structure
A valid HTML document is more than “React root div.” The doctype, lang, head metadata, and body landmarks affect rendering mode, accessibility, SEO, and social previews.
Docs: MDN document structure, HTML living standard.
Minimal solid skeleton
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Billing settings — Frontend Beauty</title>
<meta
name="description"
content="Update your plan, payment method, and invoices."
/>
<link rel="icon" href="/icon.svg" type="image/svg+xml" />
<link rel="stylesheet" href="/styles.css" />
</head>
<body>
<a class="skip-link" href="#main">Skip to content</a>
<header>…</header>
<nav aria-label="Primary">…</nav>
<main id="main">…</main>
<footer>…</footer>
<script type="module" src="/app.js"></script>
</body>
</html>
Head checklist
| Item | Why |
|---|---|
<!DOCTYPE html> |
Standards mode |
lang on <html> |
AT pronunciation, hyphenation, search |
charset early |
Avoid mojibake |
viewport |
Mobile layout |
Unique title |
Tabs, bookmarks, SEO |
description |
Snippet candidate |
| Icons / manifest | Branding, PWA |
| CSS before paint | Prevent FOUC where possible |
| Social meta (OG/Twitter) | Shares |
<meta charset="utf-8" />
Place charset in the first 1024 bytes — keep it near the top of <head>.
Body structure
<body>
<header>… site or page chrome …</header>
<nav aria-label="Primary">…</nav>
<main>
<!-- one main per page -->
</main>
<aside>… complementary …</aside>
<footer>…</footer>
</body>
- One
<main> - Label multiple
<nav>s - Skip link as early focusable control
Scripts
<script type="module" src="/app.js"></script>
Modules defer by default. Classic scripts: use defer for ordered DOM-ready execution without blocking parser as badly as sync scripts in head.
Avoid huge inline scripts before content unless required for theme FOUC prevention (small and intentional).
SPA shells
Even with client routing, the initial HTML should include:
- Correct
langand title - Meaningful shell or SSR content when possible
- Not only
<div id="root"></div>empty forever for public content pages
Interview out-loud
“I start with doctype, html lang, charset, viewport, a specific title, and description. Body uses landmarks: header, nav, one main, footer, plus a skip link. Scripts load as modules or deferred. Metadata in head covers icons and social tags when the page is shareable.”
Footguns
- Missing
lang. - Duplicate or empty titles across routes.
- Viewport locked against zoom (
user-scalable=no) harming a11y. - Multiple
mains from nested layouts. - Blocking scripts in head without defer/async.
Common generator output to fix
Many frameworks emit a minimal shell. Before production:
- Unique titles per route (SSR or prerender).
- Meta description for public pages.
langmatching content language.- Favicon links.
- One
mainlandmark. - Skip link.
<!-- Bad public docs shell -->
<div id="root"></div>
Ship at least a noscript message and, ideally, server-rendered article content for documentation sites.
Character set and title order
Put charset first, then title soon after. Some older guidance required title early for progress UI; modern browsers are fine as long as charset is early. Keep critical CSS and preloads near the top after basic meta. Defer analytics to the end of body. A clean head is easier to audit for SEO and performance regressions.
Related
Further reading
Related guides
- Accessibility Tree OverviewHow browsers build the accessibility tree from DOM and CSS — roles, names, states, what’s pruned, and how to inspect it in DevTools.
- Audio and Video ElementsNative audio/video — controls, sources, captions, autoplay policies, and accessibility requirements for media on the web.
- Autocomplete and Name Attributesname and autocomplete on form fields — password managers, autofill tokens, and why missing names break real users more than demos.
- Base Element and Relative URLsHow <base href> rewrites relative URLs for links, scripts, and forms — powerful for static hosts, dangerous when set accidentally.
- contenteditable Basicscontenteditable surfaces — what the browser gives you, sanitization, keyboard and a11y gaps, and when to pick a real editor library.