aeo

Five checks for a page that ranks but never gets cited

The five faults that keep a good page out of AI answers, each with a by-hand check, a command you can run across a site, and the fix.

A page can rank on page one and still never get cited by an assistant, quoted in an answer box, or referenced by a chatbot. That’s not a contradiction — ranking and extraction are scored on different things — but it does mean a page can look successful in Search Console while being effectively invisible to whatever is reading it for an answer.

Five things that keep a good page out of AI answers names the faults behind most of that gap. This is the diagnostic version of that list: the same five, each with the check you run by hand, the command you run across a whole site, and the fix. None of them require a rewrite; four are reordering jobs.

One caveat before the checks. Fixing these makes a page readable and liftable. It does not make anything cite you — that depends on competition, authority, freshness, and the question asked, none of which live on your page. What the list removes is the failure mode where the page never had a chance to be considered in the first place.

The five checks, and what each one catches

FaultReadiness signal it breaksCheapest fix
The answer is buried below the setupAnswer block (AEO, weight 20)Reorder the section
Every passage depends on the one beforeExtractability (AEO, 15)Restate the referent
The entity is never named plainlyEntity clarity (GEO, 15)Name it in the body
The markup and the page disagreeAnswer-relevant schema (AEO, 10)Edit both together
Nothing on the page is quotableAnswer block, lists and tablesState one figure plainly

Weights are GEOBee’s, and they’re published so they can be argued with — the three lenses documents each signal and how the 0–100 scores are built. They rank how much of a page’s readiness each fault accounts for, not how much any engine’s output depends on it. The order below is the order these are worth checking in.

Check 1: Does the first sentence answer the heading?

The fault. The heading asks a question, and the paragraph underneath spends two or three sentences on setup before it answers.

Why it survives review. It reads well. A reader going top to bottom gets context first and the answer at the end of the paragraph, which is how most good prose works. Extraction doesn’t read top to bottom — it evaluates a heading plus the passage under it, scored against a question, so the opening sentence is what gets matched and what a short answer gets built from. What an answer engine reads covers the mechanism.

Check it by hand. Pull the first sentence under every ## and ### on a page and read the pairs as a list, prose removed. If a sentence doesn’t work as a standalone answer to the heading above it, that section fails. The failures are obvious once the surrounding paragraphs are gone.

Check it at scale. If you own the markdown source, one line prints every heading-and-opening pair on a page:

awk '/^##+ /{h=$0; want=1; next} want && NF {print h" || "$0; want=0}' page.md

Run it across a content directory and you’re skimming a two-column list rather than reading pages. Against a live site, do the same thing to the rendered text: heading, then the first sentence of the block that follows it.

The fix. Move the sentence that answers the heading to the front. It’s usually already there, in sentence three or four — you’re reordering, not writing. Two or three tight sentences is enough. The 40–60 word window we use is a heuristic rather than anyone’s published rule; Google states snippet length has no fixed value and the snippet “is truncated in Google Search results as needed, typically to fit the device width” (Google Search Central, retrieved 2026-07-30). The constraint underneath is that a passage quoted whole has to survive truncation and still stand without its neighbours.

Check 2: Does each passage survive being read alone?

The fault. A paragraph reads fine in sequence and falls apart the moment it’s read alone — “it” with no antecedent in the same chunk, “as mentioned above,” a table whose meaning lives in the paragraph before it.

Why it survives review. Nobody reads their own page out of order, so the dependency is invisible to the person most likely to catch it. The pipeline splits the page into passages, and a passage can be retrieved without the one that gave it its subject.

Check it by hand. Read the paragraphs of a page in random order. Anything that stops making sense is the finding.

Check it at scale. Search for sentence-initial back-references, then check whether the referent sits in the same paragraph:

grep -nE '(^|\. )(It|This|That|These|Those|As mentioned)[ ,]' page.md

Not every hit is a fault — “This crawler” carries its own noun. Anything reaching further back than the current paragraph is a chunk-boundary risk.

The fix. Restate the noun. “It” becomes “the crawler,” “as mentioned above” becomes the thing that was mentioned above. This costs a few words per instance and nothing else.

Check 3: Is the entity named in the body, not just the title?

The fault. A support page refers to “this solution” and “our tool” nine times and names the product exactly once, in the page title.

Why it survives review. House style, usually. Repeating a product name reads as marketing to an editor, and on a page a person is reading, the title and the nav have already established what “our tool” refers to. An extracted passage carries neither. Titles, nav, and header are among the parts that don’t make the trip — what AI crawlers extract has the element-by-element inventory. A passage that never names its subject is a passage about nothing identifiable.

Check it at scale. Count how often the name appears in the body against how often a generic substitute takes its place:

grep -oiE 'YourProduct|our (tool|platform|solution)|the (tool|platform|product)' page.md \
  | tr 'A-Z' 'a-z' | sort | uniq -c | sort -rn

If the substitute wins by a wide margin, the page reads as anonymous.

The fix. Name the entity in the body at least once per major section, in a sentence that also says what it is — “GEOBee, a desktop crawler, …” rather than “the tool.” One naming sentence per section is enough; you’re not writing the name into every paragraph.

Check 4: Does the markup still agree with the page?

The fault. JSON-LD states a price, a rating, an author, or a date that no longer matches the visible page, usually because one got updated and the other didn’t.

Why it survives review. Nobody edits schema. It stops being true on its own, when a price changes on the page but not in a template field, or a CMS value is updated that the body copy doesn’t read from. There’s no error and no alert.

What it costs. Google’s guidelines are direct: “Don’t mark up content that is not visible to readers of the page,” and markup “must be a true representation of the page content” (Google Search Central, retrieved 2026-07-30). For extraction the cost is simpler — a system now holds two conflicting claims about the same fact and no clean way to choose between them.

Check it by hand. Print the JSON-LD on your ten highest-traffic pages and read it against the visible text:

curl -s "$URL" | python3 -c '
import sys, re, json
for m in re.findall(r"<script[^>]*application/ld\+json[^>]*>(.*?)</script>", sys.stdin.read(), re.S):
    print(json.dumps(json.loads(m), indent=2))
'

Check it at scale. If the drift turns out to be more than a one-off, script the same comparison — key schema fields against the equivalent visible text, one row per URL, printing only disagreements — and rerun it whenever pricing or catalog content changes.

The fix. Update both in the same edit. Better, make the template render the visible value from the same field the schema reads, so the two can’t drift apart again.

Check 5: Is there a single quotable sentence on the page?

The fault. The page is accurate and well organized, but every sentence hedges — “response times can vary,” “pricing depends on your setup.”

Why it survives review. The hedges are frequently correct, and sometimes required. But a system looking for something to quote needs a sentence that resolves: a figure, a named requirement, or a plain yes or no. Accuracy without resolution gives it nothing to carry.

Check it by hand. Skim a page for sentences containing a concrete number, a named requirement, or a yes/no claim. A page with none of those has nothing for an extractor to lift, no matter how sound the surrounding prose is.

Check it at scale. Count the sentences on a page that contain a figure at all:

grep -oE '[^.!?]*[0-9][^.!?]*[.!?]' page.md | wc -l

A zero is the finding. A low count on a page that exists to answer a quantitative question is the same finding.

The fix. Add the bounded version of the true statement rather than removing the hedge: “Response times vary with payload size; the documented target is 200 ms, and anything over 1 MB exceeds it.” You keep the caveat and gain something liftable.

Doing this across a site

Five checks on one page is a diagnosis, not an audit. The honest question isn’t whether a given page has an answer block — it’s which of your URLs fail which of the five, and whether the important ones are in that set. Every at-scale check above produces the same shape of output: one row per URL, one column per fault. That table is the artifact worth having, because it’s also the thing you re-run after a fix to see whether anything moved.

Run them in the order above, though, not in parallel. Checks 1 and 5 are the ones that change a page’s readiness most and cost the least, and a page that fails check 1 will usually fail check 5 for the same underlying reason — the writing never commits to an answer anywhere. Checks 2 and 3 are cheap to fix and easy to regress, so they’re worth re-running after any template change. Check 4 is the only one where the fault can appear without anyone touching the page.

Two of the five resist automation, and it’s worth being clear about which. Passage independence needs a reader to decide whether an antecedent is genuinely missing or merely distant, and schema agreement needs someone to judge whether two differently-worded claims mean the same thing. A crawler can flag candidates for both; it can’t close them. The other three — answer block, quotable content, and an entity tied to an organization profile — are scored signals in GEOBee, evaluated per URL with published weights, and findings and fixes shows how one failing URL turns into a finding with a fix attached.

For the full set of signals these five sit inside, see Answer Engine Optimization: a page-level guide.

On this page