Rule catalogue
Every rule goflag can report: 11 judged per page, 3 across the whole site, 4 it states but will not answer, plus the hreflang reciprocity codes.
Page rules
Judged on one page at a time, from its <head>. Each rule is a pure function of the page, which is why a finding can always be reproduced from the URL alone.
| Rule | Severity | Rigor | What it checks |
|---|---|---|---|
| title.missing | error | spec-required | Every page needs a non-empty `<title>` |
| title.length | warning | heuristic | Keep `<title>` between 10 and 60 characters |
| description.missing | warning | spec-recommended | Provide a `<meta name="description">` on every indexable page |
| description.length | warning | heuristic | Keep descriptions between 50 and 160 characters |
| canonical.missing | warning | vendor-spec | Declare a `<link rel="canonical">` so search engines pick the right URL |
| canonical.absolute | error | vendor-spec | `rel="canonical"` must be an absolute, fully-qualified URL |
| viewport.missing | warning | guideline | Declare a `<meta name="viewport">` so mobile browsers render at the right scale |
| og.title.missing | warning | vendor-spec | Set an explicit `og:title` instead of relying on `<title>` fallback |
| og.description.missing | info | vendor-spec | Set an explicit `og:description` for richer link unfurls |
| og.image.missing | warning | vendor-spec | Provide at least one `og:image` so links unfurl with a preview |
| robots.conflict | error | vendor-spec | `robots`, `googlebot`, and `X-Robots-Tag` must not contradict each other |
Site rules
Judged across the whole crawl, because no single page carries the evidence. Fixing one of these usually fixes a whole column of findings at once.
| Rule | Severity | Rigor | What it checks |
|---|---|---|---|
| hreflang.missing | error | — | Pages on a multilingual site must advertise their locale alternates |
| hreflang.sitemap-mismatch | warning | — | `<head>` alternates and sitemap locale coverage must agree |
| robots.blocks-site | error | — | `robots.txt` must not forbid crawling a site that asks to be indexed |
Rules goflag will not answer for you
Whether a title describes the page is not something a linter can decide. goflag could fake it — count words, match boilerplate, print a confident verdict — and the result would be unfalsifiable noise. So it states the question, cites what makes it a real requirement, attaches the observed facts, and stops. Ask for them with --advisories; they carry no severity, never count toward the verdict, and are only asked where the subject exists.
| Rule | Severity | Rigor | What it checks |
|---|---|---|---|
| title.descriptive | — | guideline | The `<title>` describes this specific page |
| description.accurate | — | guideline | The meta description summarizes this page truthfully |
| lang.matches-content | — | spec-required | The declared `lang` is the language the page is actually written in |
| og.image.representative | — | guideline | The `og:image` represents this page and survives the unfurl crop |
hreflang reciprocity codes
Computed cross-page and reported under missingTranslations.reciprocity rather than through the rule registry, which is why they carry a code instead of a severity. See Translations.
- missing-back-link
hreflang is only honoured when it is reciprocal. A one-way declaration is discarded, so the cluster silently degrades to no cluster at all.
`/fr/pricing` declares an alternate to `/es/precios` but the peer does not link back.
- x-default-missing
`x-default` is what a visitor whose language matches none of yours is sent to. Without it the engine guesses, and it guesses per query.
Page advertises 4 locales but no `hreflang="x-default"`.
- locale.invalid
An invalid tag is not a fallback, it is ignored: underscore instead of hyphen is enough to void the entire alternate.
`hreflang="pt_BR"` is not a valid BCP 47 tag.
- self-mismatch
Every page in a cluster must list itself. A self-reference pointing elsewhere makes the page a member of somebody else's cluster.
A page's self-referential alternate does not point at its own canonical URL.
What rigor means
Every rule records how authoritative the requirement behind it is, and cites at least one document that backs it. This is the honest answer to “says who?”: a heuristic is folklore you may knowingly ignore, a spec-required is not. A rule can never claim more authority than its strongest source carries — that is enforced in CI, not left to good intentions.
- spec-required
- A published standard says the page MUST do this. Not a matter of taste.
- spec-recommended
- A standard says SHOULD: expected practice, with room for a deliberate exception.
- vendor-spec
- A de-facto specification a single vendor controls — Open Graph, Google's canonicalization rules. Binding on the consumers that implement it, not on the web.
- guideline
- Documented best practice from a source worth trusting. No specification behind it.
- heuristic
- Industry folklore. Often useful, occasionally wrong, and never something to fix as though a standard demanded it.
Rigor is a fact about the world, so no option changes it. What your build should do about each rule is a separate question, and that is what profiles answer.
heuristicThe length thresholds cite no specification
title.length and description.length cite Google and Moz, and neither is a standard: Google states outright that title length is not a ranking factor. They ship as the display conventions they are, which is why --profile spec-only switches them off entirely rather than merely quieting them.