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.