Skip to content

The playbook

Technical SEO checklist for Google and AI answers

This technical SEO checklist is what Heddle holds every page to, so it can rank in Google, be quoted by AI assistants and read properly when shared. It has 44 items across the page head, structured data, the page itself and what crawlers read. Each item links the documentation it rests on, and 39 of them are enforced by a check that fails the build.

44 items41 primary sources39 fail the build

In the head of every page

  • A unique <title> of 60 characters or fewer that leads with the searcher's phrase. Applies to every page. Enforced by the meta check. Source: Google. Title links.
  • The brand suffix only where it fits, and never on a post (pageTitle(), meta.titleSuffix). Applies to posts. Enforced by the meta check. Source: Google. Title links. 111 of 214 titles ran long on one of our own sites, most because of the suffix.
  • A <link rel="alternate" type="application/rss+xml"> to the feed, when the site has one. Next replaces alternates wholesale, so pageMeta() carries it. Applies to every page. Enforced by the surface check. Source: RSS Advisory Board. Autodiscovery.
  • A meta description of 70 to 160 characters that answers the search. Applies to every page. Enforced by the meta check. Source: Google. Snippets.
  • A canonical link to the page's one URL. Applies to every page. Enforced by the meta check. Source: Google. Canonical URLs.
  • Open Graph: og:title, og:description, og:type (website, or article for posts), og:url, og:site_name. Applies to every page. Enforced by the meta check and the surface check. Source: The Open Graph protocol.
  • og:image at 1200x630, with og:image:width, og:image:height and og:image:alt, present in the build. The check reads the file's own header (PNG, JPEG, GIF, WebP), so a tag that says 1200x630 over another size fails, and so does an image on another host, which cannot be measured. Applies to every page. Enforced by the meta check and the surface check. Source: The Open Graph protocol. Structured properties, Meta. Images in link shares.
  • A card of its own on every post, never the home page's. Applies to posts. Enforced by the surface check. Source: The Open Graph protocol. Structured properties, Meta. Images in link shares. A shared post that shows the home card reads as a link to the home page.
  • article:published_time (and article:modified_time, article:author) in ISO 8601. Applies to posts. Enforced by the surface check. Source: The Open Graph protocol. Article.
  • A Twitter/X card: twitter:card summary_large_image, twitter:title, twitter:image, measured like og:image. Applies to every page. Enforced by the meta check and the surface check. Source: X. Cards, X. Summary card with large image.

Structured data (JSON-LD)

  • Valid JSON-LD with a stable @id on the main nodes. Applies to every page. Enforced by the agent-ready check and the surface check. Source: Google. Structured data guidelines.
  • Organization (name, url, logo, sameAs) and WebSite on the home page. Applies to home. Enforced by the surface check. Source: Google. Organization, Google. Site names.
  • A page node: WebPage or a subtype (AboutPage, ContactPage, CollectionPage, FAQPage, ProfilePage), or an Article. Applies to every page. Enforced by the surface check. Source: schema.org: WebPage.
  • dateModified on the page node. The day the content last changed, the same date as the sitemap's <lastmod>, never the build date. Applies to every page. Enforced by the surface check. Source: schema.org: dateModified, Google. Publication dates.
  • BlogPosting with headline, author (a Person with a name and a url, or a reference to one), datePublished, dateModified, image and publisher. An Organization is not an author. The url is the author's page on the site when there is one, and must then be in the build; profiles elsewhere go in sameAs. Applies to posts. Enforced by the surface check. Source: Google. Article, author markup best practices, schema.org: BlogPosting.
  • BreadcrumbList whose items carry position, name and item. Applies to every page but home. Enforced by the meta check and the surface check. Source: Google. Breadcrumb.
  • URLs in the markup that are URLs. No site origin glued onto an absolute URL (https://example.comhttps://…). Applies to every node. Enforced by the surface check. Source: schema.org: URL.
  • FAQPage, each Question with an acceptedAnswer, wherever an FAQ is shown. Applies to pages with an FAQ. Enforced by the surface check. Source: Google: FAQ.
  • Service, Product or SoftwareApplication for what is sold, where it applies. Applies to offering pages. Not gated by a check yet. Source: schema.org: Service.
  • No Review or AggregateRating unless real reviews are shown on that page (surface.allowRatings). Never by default. Enforced by the surface check. Source: Google. Review snippets, self-serving reviews.
  • All dates in ISO 8601. A date with a time carries the offset of surface.timezone that day (zoned() in seo.ts); an Event's startDate has a time. A UTC time once moved an evening event to the next day. Applies to every node. Enforced by the surface check. Source: Google. Publication dates, Google. Event.
  • One Organization with a stable @id, a url and a logo, that every page's publisher references by @id; never a second node for the same company. alternateName for the spellings directories use. Applies to every page. Enforced by the surface check. Source: Google. Organization.
  • Event complete (start with offset, location, an image that resolves), described once under a stable @id that other pages point at. Applies to event pages. Not gated by a check yet. Source: Google. Event.
  • SoftwareApplication offers at price 0 only when it is free, with codeRepository and license only when the source is public. Applies to free software. Not gated by a check yet. Source: Google. Software app.
  • An address stated once, in one form everywhere (name, address, phone), the geo point on the building, and areaServed for the markets. A second spelling of the address cost a map-pack position. Applies to service companies with an office. Not gated by a check yet. Source: Google. Local business.

On the page

For crawlers and assistants

  • sitemap.xml with every indexable URL and its <lastmod>: the day the content changed, the same as the page's dateModified, never after the build and not the build date on every URL (surface.launched excuses launch day). Applies to the site. Enforced by the surface check. Source: Google. Build a sitemap. ("Google uses the lastmod value if it's consistently and verifiably accurate").
  • An RSS feed whose items carry dc:creator and category. Applies to sites with posts. Enforced by the surface check. Source: RSS 2.0, Dublin Core. Creator.
  • X-Robots-Tag. Noindex on share images and /_next/static, written by heddle aeo into _headers; Google crawled 128 cards as pages on one of our own sites. Social networks fetch the card and ignore the header. Applies to the site. Enforced by the canary. Source: Google. Robots meta tag and X-Robots-Tag.
  • One canonical host and no trailing slash. The other host and a slashed path answer 301 (or 308) before the asset layer, never 307. Applies to the site. Enforced by the canary and the urls check. Source: Google. Redirects.
  • robots.txt that names the sitemap and lets the answer-engine crawlers in: GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, Claude-User, Claude-SearchBot, PerplexityBot, Perplexity-User, Google-Extended, Applebot-Extended, Bingbot. Blocking a training crawler is a business decision, allowed when written in agentReady.blocked with its reason. Applies to the site. Enforced by the agent-ready check. Source: OpenAI. Crawlers, Perplexity. Crawlers, Google. Common crawlers.
  • llms.txt and llms-full.txt, and a Markdown twin of every page announced by a Link header and a <link rel="alternate" type="text/markdown"> in the head. Cloudflare reads 100 _headers rules, so past about 80 pages the header comes from the Worker (agentReady.linkHeaders: "runtime"). Applies to the site. Enforced by the agent-ready check and the surface check and the canary. Source: The llms.txt proposal, Cloudflare. Headers.
  • Each twin says what its page says. Its prose is on the page and its heading is the page's H1. Applies to every twin. Enforced by the agent-ready check. City twins once answered the office question differently from their pages.
  • Google does not use llms.txt (15 May 2026); it serves the other assistants. Not gated by a check yet. Source: Google Search Central.

Answer engines (AEO and GEO)

AEO is SEO. Google said on 15 May 2026 that its AI features rest on core ranking and need no special files or markup, and on our own sites what moved citations was ranking. So there is no separate AEO surface to build; there is the surface above, read by more machines. What changes is emphasis:

  • Answer first. The paragraph under the H1 answers the page's question in 40 to 80 words, and headings are the questions people ask, each answered in its first sentence (agent-ready, answers). Assistants lift those whole.
  • Answer the prompts, not only the searches. People ask answer engines "best X for Y" and "how do I…". List those buyer questions in topics.json buyerQuestions and give each a page or an FAQ entry that answers it with something checkable. Where competitors are cited for badges, a number on file is the answer.
  • One entity, corroborated. One Organization @id on every page, its canonical description pasted verbatim on every sameAs profile, and a brand page with a JSON manifest.
  • Let the crawlers in, and write down any you keep out.
  • Answer engines cite before Google ranks. A page Google had not indexed was cited by ChatGPT on one of our own sites, so measure citations separately.
  • Video is the most-cited source. YouTube led the citations the source site measured (35 across 31 terms); see the playbook.
  • Answer the threads that rank, as a named person, one link, only where it answers, after reading the thread. Scripts get a 403 from the forums that matter, and an agent posting there is spam. An agent may draft the answer; a person posts it.

The spam policies Heddle stays inside

No keyword stuffing, no hidden text, no doorway pages built for a phrase with nothing behind it (the uniqueness check), no invented reviews or ratings, no dates moved forward without a change, and no claim without evidence on file. Each of these is in Google's spam policies, and each has a check or a rule that stops it.

Generated from the Heddle repository at ddb1b16.

Questions

Does llms.txt help a site rank in Google?

No. Google said on 15 May 2026 that Google Search does not use llms.txt. Other assistants do fetch it, so it stays on the checklist as a cheap file for them, not as a ranking lever.

Is AEO a separate checklist from SEO?

Mostly not. Google's AI features rest on its core ranking, and on the sites Heddle was built from, what moved citations was ranking. What changes is emphasis: answer the question under the H1, phrase headings as questions, and let the answer-engine crawlers in.

How is each item checked?

Heddle runs its checks on the built pages, locally and in CI. A page that misses an enforced item fails the build. The other 5 items are written guidance an agent or a person applies.

Work with us

Let the agents bring you the leads.

Tell us about your business and who buys from you. On a short call we'll show you the searches your buyers make where you don't show up yet, and what the agents would do about them in their first month.

On the call, for your site

  1. The searches your buyers makeMeasured, with how many people make each one
  2. Where you show up, and where you don'tOn Google and in ChatGPT's answers
  3. The agents' first monthThe pages, fixes and links they would start with