HTML: Document Structure & Metadata
Every HTML document has a consistent structure. The <head> is for metadata and resources; the <body> is for visible content.
Document Boilerplate
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Page description for SEO, max 155 chars">
<title>Page Title — Site Name</title>
<!-- Canonical URL (prevent duplicate content) -->
<link rel="canonical" href="https://example.com/page">
<!-- Favicons -->
<link rel="icon" href="/favicon.ico" sizes="32x32">
<link rel="icon" href="/icon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<link rel="manifest" href="/site.webmanifest">
<!-- CSS -->
<link rel="stylesheet" href="/styles.css">
<!-- Preconnect to external origins (speeds up DNS + TLS) -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<!-- Preload critical resources -->
<link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/hero.webp" as="image">
</head>
<body>
<!-- content -->
<script src="/app.js" defer></script>
</body>
</html>Key Meta Tags
<!-- Character encoding — always UTF-8, always first in <head> -->
<meta charset="UTF-8">
<!-- Viewport — essential for responsive design -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- On iOS, prevent font size adjustment in landscape -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<!-- SEO -->
<meta name="description" content="Clear description, 120-155 characters">
<meta name="robots" content="index, follow">
<meta name="robots" content="noindex, nofollow"> <!-- prevent indexing -->
<!-- Theme color (browser chrome on mobile) -->
<meta name="theme-color" content="#0070f3">
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="#000000">
<!-- Referrer policy -->
<meta name="referrer" content="strict-origin-when-cross-origin">Open Graph & Social Meta Tags
<!-- Open Graph — controls how page looks when shared on Facebook, LinkedIn, etc. -->
<meta property="og:type" content="website">
<meta property="og:url" content="https://example.com/page">
<meta property="og:title" content="Page Title">
<meta property="og:description" content="Description shown in the link preview">
<meta property="og:image" content="https://example.com/og-image.jpg">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:site_name" content="My Site">
<!-- Twitter Card -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@mysite">
<meta name="twitter:creator" content="@author">
<meta name="twitter:title" content="Page Title">
<meta name="twitter:description" content="Description">
<meta name="twitter:image" content="https://example.com/twitter-image.jpg">Script Loading Strategies
<!-- Blocking — stops HTML parsing until script is downloaded and executed (avoid) -->
<script src="app.js"></script>
<!-- defer — downloads in parallel, executes AFTER HTML parsing completes, in order -->
<script src="app.js" defer></script>
<!-- async — downloads in parallel, executes IMMEDIATELY when ready (ignores order) -->
<script src="analytics.js" async></script>
<!-- type="module" — deferred by default, own scope, supports import -->
<script type="module" src="app.mjs"></script>
<!-- Inline script — executes immediately -->
<script>
document.getElementById('app').style.display = 'block';
</script>
<!-- Best practice: put scripts before </body> OR use defer for head scripts -->Link Relationships
<!-- Stylesheet -->
<link rel="stylesheet" href="styles.css" media="print"> <!-- only for print -->
<link rel="stylesheet" href="dark.css" media="(prefers-color-scheme: dark)">
<!-- Alternate versions -->
<link rel="alternate" hreflang="uk" href="https://example.com/uk/page">
<link rel="alternate" hreflang="x-default" href="https://example.com/page">
<!-- RSS feed -->
<link rel="alternate" type="application/rss+xml" href="/rss.xml" title="Blog RSS">
<!-- DNS prefetch (cheap — just DNS lookup) -->
<link rel="dns-prefetch" href="https://api.example.com">
<!-- Preconnect (DNS + TCP + TLS — more expensive, use sparingly) -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<!-- Prefetch next page (low priority background fetch) -->
<link rel="prefetch" href="/next-page.html">
<!-- Prerender next page (render in background, instant navigation) -->
<link rel="prerender" href="/next-page.html">Keep your own version of these notes — editable, searchable, and organised by your stack.
Start free