Cheatsheet

Everything worth shipping, written out.

The reasoning behind each of these is on reach and credence. This page is just the markup. Required means a page is materially worse without it. Optional means it is cheap, occasionally decisive, and safe to skip where it does not apply.

The head

Every page, not only the home page — any of them may be the one that gets shared.

<html lang="en">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

<!-- unique per page. ~60 chars of title, ~155 of description -->
<title>Page — what it is</title>
<meta name="description" content="…">
<link rel="canonical" href="https://example.org/page">

Sharing. Without these a shared link renders as a bare URL — no title, no description, nothing.

<meta property="og:type" content="article">
<meta property="og:title" content="Page — what it is">
<meta property="og:description" content="…">
<meta property="og:url" content="https://example.org/page">
<meta property="og:site_name" content="Site">
<meta name="twitter:card" content="summary_large_image">

<!-- 1200x630 -->
<meta property="og:image" content="https://example.org/og.png">

Icons. Real files at real paths — never an inline data: URI, which a crawler has nothing to fetch.

<link rel="icon" href="/favicon.ico" sizes="any">
<link rel="icon" href="/favicon.svg" type="image/svg+xml">

<!-- optional, 180x180 -->
<link rel="apple-touch-icon" href="/apple-touch-icon.png">

Structured data

One <script type="application/ld+json"> in the head. The common mistake is declaring that a collection has members and then listing none of them.

{
  "@context": "https://schema.org",

  // Article, Product, Organization, Collection…
  "@type": "TechArticle",

  "headline": "Page — what it is",
  "description": "…",
  "url": "https://example.org/page",

  // optional, and useful once findings start to age
  "datePublished": "2026-08-10",
  "dateModified": "2026-08-10",

  "isPartOf": {
    "@type": "Collection",
    "name": "Site",
    "url": "https://example.org/"
  },

  // ENUMERATE. A count with no members tells a reader nothing exists.
  "hasPart": [
    {
      "@type": "VisualArtwork",
      "name": "Item one",
      "url": "https://example.org/items/1",
      "identifier": {
        "@type": "PropertyValue",
        "propertyID": "sku",
        "value": "0001"
      }
    }
  ]
}

One optional field worth knowing: disambiguatingDescription, defined as distinguishing an item from similar ones. Useful if your name collides with a common noun or another product — but it is a plain description field with no conditional behaviour, so every clause must be worth saying in an answer where nobody was confused.

llms.txt

Plain text at your root. A proposed convention rather than a standard, and support is uneven — Google does not read it. Cheap enough to write anyway.

# site name
> example.org — one line on what this is

An opening paragraph in plain prose. Third person throughout: describe the
thing, never address the reader. No "you", no imperatives.

## what this is
The short version, in sentences rather than fields.

## what this is not
The exclusions that a reader would otherwise have to guess. Cheap, and
disproportionately effective if your category attracts suspicion.

## 
Whatever a stranger would need in order to describe the site accurately
without you present.

- [data.json](https://example.org/data.json): what is in it, in one line

robots.txt and sitemap.xml

# robots.txt
User-agent: *
Allow: /

Sitemap: https://example.org/sitemap.xml
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://example.org/page</loc>
    <!-- move this only when the file itself moves -->
    <lastmod>2026-08-10</lastmod>
  </url>
</urlset>

Generate lastmod from the file's own timestamp rather than typing it. A hand-written date is a claim that goes stale silently, in the one document whose entire job is reporting change.

Next: how to test — including how to check that any of this actually landed.