Skip to content

Check methodology

Every check this product can report, what it measures, how it was determined, and what it cannot measure. The rules are published as data at /methodology/checks.json so they can be read, diffed and argued with without reading the engine.

Ruleset version 5 · definitions version 1 · 31 checks · scored: 20

How to read this page

Scored means the check can count towards the checklist score when it applies and is measurable. A check marked not scored is reported and never counted — accessibility and generative-search findings are shown because they are worth knowing, not because they change a number. The score’s denominator is always shown beside it, and a page where nothing scorable applied has no score rather than a zero.

Not measured is a first-class answer. Where a check could not be evaluated the report says so, and it is excluded from the score rather than counted as a failure.

SEO

Whether search engines can discover, crawl, and understand this page.

Answer clarity

Whether the page answers the question a reader arrived with, and whether that answer is reachable.

AI search

The evidence a generative answer could draw on, plus any visibility that has actually been measured.

Additional improvements

Worth doing for readers and assistive technology. Not search ranking signals, and never scored as such.

Search

HTTPS connection https

What it measures. Whether the URL that answered is served over HTTPS, after following redirects.

How it was determined. Parsed from the response the server returned, recorded on the scan, and re-read from the stored report rather than re-derived later.

What it cannot measure.

  • Whether the certificate is valid for every hostname the page loads from.
  • Whether the HTTP address still resolves and answers.

What to do. Serve the site over HTTPS and redirect the HTTP address to it.

Free tool: mixed-content

Page title title

What it measures. Whether the head contains a title element and how long it is.

How it was determined. Parsed from the response the server returned, recorded on the scan, and re-read from the stored report rather than re-derived later.

What it cannot measure.

  • Whether Google will use it. Google rewrites titles it considers unhelpful, whatever this says.
  • Whether the title reads well, which is a judgement about your copy.

What to do. Write one title per page, specific to that page, and put the distinguishing words first.

Free tool: serp

Meta description description

What it measures. Whether a meta description is present and its length.

How it was determined. Parsed from the response the server returned, recorded on the scan, and re-read from the stored report rather than re-derived later.

What it cannot measure.

  • Whether it will be shown. Google frequently writes its own snippet from page text.
  • Whether a missing description costs you clicks — that depends on the query.

What to do. Add a meta description. A missing one is a missed opportunity rather than an error.

Free tool: serp

Indexing directives index

What it measures. The robots meta tag and X-Robots-Tag as sent, read as data rather than as prose.

How it was determined. Parsed from the response the server returned, recorded on the scan, and re-read from the stored report rather than re-derived later.

What it cannot measure.

  • Whether a page is actually indexed. That requires Search Console or an index check.
  • Whether a directive came from your code or a CDN rule.

What to do. Remove a noindex you did not intend. A deliberate one should stay.

Free tool: robots-tester

Canonical URL canonical

What it measures. Whether the page declares a canonical and what it points at.

How it was determined. Parsed from the response the server returned, recorded on the scan, and re-read from the stored report rather than re-derived later.

What it cannot measure.

  • Which URL wins when two pages disagree. Google decides that.
  • Whether a canonical sent as an HTTP header says something different — see the headers tool.

What to do. Declare a self-referencing canonical unless duplicates genuinely exist.

Free tool: canonical-checker

Main heading h1

What it measures. Whether the source HTML contains exactly one h1 and its text.

How it was determined. Parsed from the response the server returned, recorded on the scan, and re-read from the stored report rather than re-derived later.

What it cannot measure.

  • Whether the heading is visually hidden or styled to look like something else.
  • Whether the outline reads well to a person.

What to do. Use one h1 that describes the page, and let the sections below it be h2s.

Free tool: structured-data

Mobile viewport viewport

What it measures. Whether a viewport meta tag is present.

How it was determined. Parsed from the response the server returned, recorded on the scan, and re-read from the stored report rather than re-derived later.

What it cannot measure.

  • Whether the layout actually works on a phone. That needs rendering at a mobile width.
  • Whether a CSS media query does the same job instead.

What to do. Add a viewport meta tag with width=device-width and an initial scale of 1.

Free tool: meta-tags

Image alternative text alt

What it measures. How many images in the source HTML carry an alt attribute, including empty ones.

How it was determined. Parsed from the response the server returned, recorded on the scan, and re-read from the stored report rather than re-derived later.

What it cannot measure.

  • Whether the text describes the image, which no tool can judge.
  • Whether an image is decorative, where an empty alt is the correct answer.

What to do. Give informative images real alt text and decorative ones an empty alt.

Free tool: structured-data

Snippet controls aeo-snippet-controls

What it measures. Whether directives limit how much of the page a search engine may show.

How it was determined. Parsed from the response the server returned, recorded on the scan, and re-read from the stored report rather than re-derived later.

What it cannot measure.

  • Whether the directive is being honoured, which the engine does not report.
  • Whether limiting the snippet is the right choice for you.

What to do. Remove nosnippet or max-snippet limits if you want the full text quotable.

Free tool: meta-tags

Opening answer passage aeo-answer-lead

What it measures. Whether the page opens with a self-contained passage that answers the obvious question.

How it was determined. Parsed from the response the server returned, recorded on the scan, and re-read from the stored report rather than re-derived later.

What it cannot measure.

  • Whether that passage is the one anyone would quote.
  • Whether a quote would ever be displayed — that is not something a page controls.

What to do. Open with a direct answer in two or three sentences, before the build-up.

Free tool: query-fanout

Structured data

Structured data formats schema-presence

What it measures. Which structured data formats appear: JSON-LD, microdata, RDFa, and their @type values.

How it was determined. Parsed from the response the server returned, recorded on the scan, and re-read from the stored report rather than re-derived later.

What it cannot measure.

  • Whether the markup is valid. That is the JSON-LD syntax check.
  • Whether the values are true statements about the business.

What to do. Add JSON-LD for the entity the page represents, when the page actually represents one.

Free tool: schema-validator

JSON-LD syntax schema-json

What it measures. Whether each JSON-LD block parses as JSON.

How it was determined. Parsed from the response the server returned, recorded on the scan, and re-read from the stored report rather than re-derived later.

What it cannot measure.

  • Whether the parsed markup is eligible for a rich result. That is a feature-requirements question.
  • Whether microdata or RDFa on the page is valid — neither is parsed here.

What to do. Fix the JSON. A block that does not parse is invisible to every consumer.

Free tool: schema-validator

JSON-LD context schema-context

What it measures. Whether each JSON-LD block declares an @context of schema.org.

How it was determined. Parsed from the response the server returned, recorded on the scan, and re-read from the stored report rather than re-derived later.

What it cannot measure.

  • Whether the types used inside it exist in the vocabulary. An unknown type parses and means nothing.
  • Whether a nested node inherits the context correctly, beyond the depth we walk.

What to do. Add "@context": "https://schema.org" to every block.

Free tool: schema-validator

Common schema properties schema-fields

What it measures. Which commonly expected properties are present on each entity type.

How it was determined. Parsed from the response the server returned, recorded on the scan, and re-read from the stored report rather than re-derived later.

What it cannot measure.

  • Whether the values are correct.
  • Whether these properties are the ones Google asks for today — that list changes without notice.

What to do. Fill in the properties the entity genuinely has. Never invent a value to satisfy a checker.

Free tool: schema-validator

Discovery files

robots.txt discovery robots

What it measures. Whether /robots.txt answers and whether its content parses as a robots file.

How it was determined. Parsed from the response the server returned, recorded on the scan, and re-read from the stored report rather than re-derived later.

What it cannot measure.

  • Whether the rules inside it are the ones you want. Use the robots tester for a specific URL and crawler.
  • Whether a CDN or WAF answers differently for a bot.

What to do. Serve a robots.txt that parses, and point it at your sitemap.

Free tool: robots-tester

Sitemap discovery sitemap

What it measures. Whether /sitemap.xml answers and how many URLs it contains.

How it was determined. Parsed from the response the server returned, recorded on the scan, and re-read from the stored report rather than re-derived later.

What it cannot measure.

  • Whether the listed URLs work. The sitemap validator samples them.
  • Whether every page on the site is listed.

What to do. Publish a sitemap, keep it current, and declare it in robots.txt.

Free tool: sitemap-validator

Performance

Reserved image dimensions image-size

What it measures. How many images in the source declare width and height attributes.

How it was determined. Parsed from the response the server returned, recorded on the scan, and re-read from the stored report rather than re-derived later.

What it cannot measure.

  • The real layout shift this page causes. That is a field measurement, and it needs traffic.
  • Whether a CSS rule or aspect-ratio already reserves the space.

What to do. Set width and height on images, or reserve the space in CSS.

Free tool: vitals

HTML response weight html-size

What it measures. The byte size of the HTML response as received, compressed or not as sent.

How it was determined. Parsed from the response the server returned, recorded on the scan, and re-read from the stored report rather than re-derived later.

What it cannot measure.

  • Whether the page is slow. HTML is usually a small part of the total, and assets are separate requests.
  • The rendered size after JavaScript runs.

What to do. Send less HTML, or compress it. Check the content-encoding header first.

Free tool: vitals

Server response time response-time

What it measures. Time to first byte for the audited request, from our machine.

How it was determined. Parsed from the response the server returned, recorded on the scan, and re-read from the stored report rather than re-derived later.

What it cannot measure.

  • What a visitor experiences. One measurement from one location is a sample, not a field number.
  • Whether the delay is your origin, your CDN, or the network between.

What to do. Cache at the edge, and look at the server side if the first byte is slow everywhere.

Free tool: headers

Synchronous head scripts blocking-scripts

What it measures. Script tags in the head with neither async nor defer.

How it was determined. Parsed from the response the server returned, recorded on the scan, and re-read from the stored report rather than re-derived later.

What it cannot measure.

  • Whether the script is actually blocking in practice, which depends on where and how it is inserted.
  • The cost in milliseconds. That is a lab measurement.

What to do. Add async or defer, or move the script out of the head.

Free tool: vitals

Image loading strategy image-loading

What it measures. Which images declare loading="lazy" and which declare fetchpriority.

How it was determined. Parsed from the response the server returned, recorded on the scan, and re-read from the stored report rather than re-derived later.

What it cannot measure.

  • Whether lazy-loading is correct for a particular image. The largest one above the fold should not be lazy.
  • The effect on Core Web Vitals, which needs a measurement.

What to do. Lazy-load below-the-fold images and leave the hero image eager.

Free tool: vitals

Generative search

Text available in source geo-readable

What it measures. How much readable text is present in the HTML the server returns.

How it was determined. Parsed from the response the server returned, recorded on the scan, and re-read from the stored report rather than re-derived later.

What it cannot measure.

  • Whether that text is any good.
  • What a browser would show after JavaScript runs — a client-rendered page looks thin here and may be fine.

What to do. Serve the content in the HTML if you want anything outside a browser to read it.

Free tool: visibility

Content structure geo-outline

What it measures. The heading outline of the document as sent.

How it was determined. Parsed from the response the server returned, recorded on the scan, and re-read from the stored report rather than re-derived later.

What it cannot measure.

  • Whether the structure reflects the argument the page makes.
  • Anything about headings a script inserts later.

What to do. Use headings that describe their sections, in a single sensible hierarchy.

Free tool: visibility

Author or contributor signal geo-author

What it measures. Whether the page declares an author, by name, by link, or in structured data.

How it was determined. Parsed from the response the server returned, recorded on the scan, and re-read from the stored report rather than re-derived later.

What it cannot measure.

  • Whether that person exists or knows the subject.
  • Whether a byline is appropriate — plenty of good pages correctly have none.

What to do. Attribute the page to a real person and link to something that shows why they would know.

Free tool: visibility

Published or updated date geo-date

What it measures. Whether the page declares a published or modified date a machine can read.

How it was determined. Parsed from the response the server returned, recorded on the scan, and re-read from the stored report rather than re-derived later.

What it cannot measure.

  • Whether the date is true.
  • Whether the content is current — a fresh date on stale text is worse than none.

What to do. Declare a modified date that changes when the content actually changes.

Free tool: visibility

Links to supporting sources geo-sources

What it measures. Outbound links, and whether any point at primary or reference sources.

How it was determined. Parsed from the response the server returned, recorded on the scan, and re-read from the stored report rather than re-derived later.

What it cannot measure.

  • Whether the sources support the claim. That is a reading of the page.
  • Whether a link to a .gov domain is relevant to your subject.

What to do. Link to the primary source for each claim that has one.

Free tool: visibility

About or contact discovery geo-identity

What it measures. Whether the page or its navigation links to an about or contact page.

How it was determined. Parsed from the response the server returned, recorded on the scan, and re-read from the stored report rather than re-derived later.

What it cannot measure.

  • Whether the business is real or reachable.
  • Whether the entity is who it says it is.

What to do. Link to a page that says who publishes this site and how to reach them.

Free tool: visibility

Generative search eligibility needs review geo-eligibility

What it measures. Whether anything we recorded blocks or discourages a generative search engine from using this page.

How it was determined. Parsed from the response the server returned, recorded on the scan, and re-read from the stored report rather than re-derived later.

What it cannot measure.

  • Whether the page is cited by any AI answer. That is measured elsewhere, and only when it has been bought.
  • Anything about a model that never crawls the page.

What to do. Check the blocked-crawler findings above before changing anything else.

Free tool: ai-crawler-check

Accessibility and reader experience

Heading structure a11y-heading-structure

What it measures. Whether heading levels are sequential and no level is skipped.

How it was determined. Parsed from the response the server returned, recorded on the scan, and re-read from the stored report rather than re-derived later.

What it cannot measure.

  • Whether the document is usable with a screen reader, which needs a real assistive technology.
  • Whether a skipped level matters on a particular page.

What to do. Do not skip levels. Use h3 because the section is a subsection, not because it looks right.

Free tool: visibility

Document language a11y-document-language

What it measures. Whether the html element declares a language and whether it is a valid language tag.

How it was determined. Parsed from the response the server returned, recorded on the scan, and re-read from the stored report rather than re-derived later.

What it cannot measure.

  • Whether the page is actually written in that language.
  • What to do about a page that mixes languages, which the specification leaves to the author.

What to do. Set lang on the html element to the language the page is written in.

Free tool: meta-tags

Checks this page does not define

Three families are generated from data rather than listed above: the per-crawler AI access findings (one per crawler probed, named in the report), the per-feature rich-result findings (one per schema type Google supports), and the cross-page findings from a whole-site crawl. Their rules live in lib/checks/ and lib/crawl/ and are versioned by the same ruleset number.

Withdrawn checks are listed in lib/scope.ts. A saved report that contains one is filtered at read time rather than rewritten, because a stored report is a record of what was true on the day it ran.

Open source, deliberately

The rules are published, not the engine. Anyone can read what each check does, implement the same check, and disagree with ours on the evidence. That is the point: a finding you cannot inspect is a finding you have to take on trust.

Read the definitions as JSON What crawlwise cannot tell you