HTML
05 / 12

Document Structure & Metadata

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