AEO (Answer Engine Optimization)
[← Back to Home](/docs/rules)
Checks for whether AI answer engines (ChatGPT browsing, Perplexity, Google AI Overviews, voice assistants) can access a page at all, and whether its content is structured so an answer engine can lift it directly into a response. Source: src/lib/aeoAudit.ts (analyzeAEO, analyzeAEOSiteSignals).
31 rules in this category.
aeo-ai-crawlers-blocked
robots.txt blocks N AI search crawler(s)
| Severity | Weight | Category |
|---|---|---|
| High | 12 pts | AEO (Answer Engine Optimization) |
What triggers it & why it matters: The named AI search or browsing crawlers (OAI-SearchBot, ChatGPT-User, PerplexityBot, Claude-SearchBot, DuckAssistBot, …) are disallowed, directly or by a site-wide "User-agent: *" rule. These are the crawlers assistants use to fetch pages they cite, so the site can't be cited by them. Training-only crawlers are reported separately (aeo-ai-training-blocked). Gate: while this fails, the category score is capped at 40, so strengths elsewhere can't hide it.
How to fix it & effect on score: Allow the AI search and browsing crawlers you want to be cited by. You can keep blocking training-only crawlers such as GPTBot and CCBot. Fixing this removes the 12 pts deduction from the AEO (Answer Engine Optimization) category score on the next scan.
Evidence: official requirement (documented by the engine or standard).
aeo-ai-crawler-firewall-block
Requests with an AI crawler user-agent get HTTP (status)
| Severity | Weight | Category |
|---|---|---|
| High | 10 pts | AEO (Answer Engine Optimization) |
What triggers it & why it matters: Requested as OAI-SearchBot (the crawler ChatGPT uses to fetch pages it cites) the page returns an error status, while a normal browser gets it. A CDN/WAF or bot-management rule blocks AI crawlers regardless of robots.txt. Gate: while this fails, the category score is capped at 40, so strengths elsewhere can't hide it.
How to fix it & effect on score: Allow verified AI search crawlers in your CDN/WAF bot settings (e.g. Cloudflare "Verified Bots", "Block AI bots"). Fixing this removes the 10 pts deduction from the AEO (Answer Engine Optimization) category score on the next scan.
Evidence: measured on the live site at scan time.
aeo-ai-crawler-network-block
A request identifying as an AI crawler failed outright
| Severity | Weight | Category |
|---|---|---|
| High | 10 pts | AEO (Answer Engine Optimization) |
What triggers it & why it matters: The OAI-SearchBot request couldn't complete at all while a browser request succeeded: a firewall or bot-management rule drops AI crawlers at the connection level. Gate: while this fails, the category score is capped at 40, so strengths elsewhere can't hide it.
How to fix it & effect on score: Check CDN/WAF rules for entries blocking AI crawlers and allow the search crawlers you want to be cited by. Fixing this removes the 10 pts deduction from the AEO (Answer Engine Optimization) category score on the next scan.
Evidence: measured on the live site at scan time.
aeo-answer-schema-missing
Q&A-style content isn't marked up as FAQPage/QAPage
| Severity | Weight | Category |
|---|---|---|
| Medium | 7 pts | AEO (Answer Engine Optimization) |
What triggers it & why it matters: Found N question-style heading(s) (e.g. "(actual value found on the page, truncated)") but no matching FAQPage, QAPage, or HowTo structured data. Answer engines strongly favor content that's explicitly marked up this way when choosing what to quote or cite.
How to fix it & effect on score: Wrap existing question/answer content in FAQPage (or HowTo for step-by-step content) JSON-LD so each question and its answer are machine-readable. Fixing this removes the 7 pts deduction from the AEO (Answer Engine Optimization) category score on the next scan.
aeo-freshness-missing
No publish or last-updated date found
| Severity | Weight | Category |
|---|---|---|
| Medium | 6 pts | AEO (Answer Engine Optimization) |
What triggers it & why it matters: No article:modified_time meta tag, <time datetime> element, or dateModified/datePublished in structured data was found. Answer engines favor demonstrably current content, especially for anything time-sensitive.
How to fix it & effect on score: Add a visible last-updated date wrapped in a <time datetime="..."> element, and set dateModified in your JSON-LD. Fixing this removes the 6 pts deduction from the AEO (Answer Engine Optimization) category score on the next scan.
aeo-intro-paragraph
No clear introductory paragraph found
| Severity | Weight | Category |
|---|---|---|
| Medium | 6 pts | AEO (Answer Engine Optimization) |
What triggers it & why it matters: There's no <p> element near the top of the page. Answer engines look for a short, self-contained paragraph early in the content that directly states the answer or topic before pulling in supporting detail.
How to fix it & effect on score: Open the main content with a concise paragraph (2–3 sentences) that directly answers the page's core question before going into detail. Fixing this removes the 6 pts deduction from the AEO (Answer Engine Optimization) category score on the next scan.
What a pass looks like: Page opens with a substantive paragraph an answer engine can quote
aeo-semantic-container
No <main> or <article> element wraps the content
| Severity | Weight | Category |
|---|---|---|
| Medium | 6 pts | AEO (Answer Engine Optimization) |
What triggers it & why it matters: Without a <main>, <article>, or role="main" landmark, crawlers have to guess where navigation/boilerplate ends and the actual answerable content begins.
How to fix it & effect on score: Wrap the primary content in a single <main> (or <article> for individual posts) element. Fixing this removes the 6 pts deduction from the AEO (Answer Engine Optimization) category score on the next scan.
What a pass looks like: Content is wrapped in a semantic main/article landmark
aeo-author-missing
No author or byline found
| Severity | Weight | Category |
|---|---|---|
| Medium | 5 pts | AEO (Answer Engine Optimization) |
What triggers it & why it matters: No author meta tag, article:author, rel=author link, or JSON-LD author property was found. Answer engines weigh clear authorship as part of judging whether content is trustworthy enough to cite.
How to fix it & effect on score: Add a visible byline plus matching author markup (meta author, or an author property in your Article/BlogPosting JSON-LD). Fixing this removes the 5 pts deduction from the AEO (Answer Engine Optimization) category score on the next scan.
aeo-question-headings
No subheadings are phrased as questions
| Severity | Weight | Category |
|---|---|---|
| Medium | 5 pts | AEO (Answer Engine Optimization) |
What triggers it & why it matters: None of the page's H2/H3 headings are phrased as direct questions. Answer engines tend to extract a heading and the paragraph beneath it verbatim when the heading itself matches how people phrase queries.
How to fix it & effect on score: Rephrase a few section headings as the questions they answer, e.g. "How much does it cost?" instead of "Pricing". Fixing this removes the 5 pts deduction from the AEO (Answer Engine Optimization) category score on the next scan.
What a pass looks like: N of N subheadings are phrased as questions
aeo-scannable-structure
No lists or tables found in substantial content
| Severity | Weight | Category |
|---|---|---|
| Medium | 5 pts | AEO (Answer Engine Optimization) |
What triggers it & why it matters: The page has roughly N words but no <ul>/<ol> lists or <table> elements. Answer engines preferentially extract and summarize list- and table-formatted content over long unbroken paragraphs.
How to fix it & effect on score: Break out steps, features, comparisons, or specs into bulleted/numbered lists or a table where it makes sense. Fixing this removes the 5 pts deduction from the AEO (Answer Engine Optimization) category score on the next scan.
What a pass looks like: Page includes list or table structure that's easy for answer engines to extract
aeo-intro-paragraph-thin
Opening paragraph is too short to serve as a direct answer
| Severity | Weight | Category |
|---|---|---|
| Low | 4 pts | AEO (Answer Engine Optimization) |
What triggers it & why it matters: The first paragraph is only N characters ("(actual value)"), too short to give an answer engine a self-contained statement to quote.
How to fix it & effect on score: Expand the opening paragraph to 2–3 sentences that fully answer the page's main question in plain language. Fixing this removes the 4 pts deduction from the AEO (Answer Engine Optimization) category score on the next scan.
aeo-no-qa-content
No question-and-answer content or schema found
| Severity | Weight | Category |
|---|---|---|
| Low | 4 pts | AEO (Answer Engine Optimization) |
What triggers it & why it matters: Answer engines (ChatGPT, Perplexity, Google AI Overviews) disproportionately cite pages that explicitly answer a question near the top of the content. This page has neither Q&A-phrased headings nor FAQPage/HowTo schema.
How to fix it & effect on score: Add a short FAQ or Q&A section covering the questions people actually ask about this topic, marked up with FAQPage structured data. Fixing this removes the 4 pts deduction from the AEO (Answer Engine Optimization) category score on the next scan.
aeo-citations
No outbound links to external sources
| Severity | Weight | Category |
|---|---|---|
| Low | 3 pts | AEO (Answer Engine Optimization) |
What triggers it & why it matters: The page makes claims without linking out to any external source, study, or reference. Citing sources is one of the signals answer engines use to gauge whether a page is safe to quote as an authority.
How to fix it & effect on score: Where relevant, link to the original sources, studies, or documentation backing up factual claims. Fixing this removes the 3 pts deduction from the AEO (Answer Engine Optimization) category score on the next scan.
What a pass looks like: Page links out to external sources
aeo-llms-txt-missing
No llms.txt file found
| Severity | Weight | Category |
|---|---|---|
| Low | 3 pts | AEO (Answer Engine Optimization) |
What triggers it & why it matters: llms.txt is an emerging convention that gives AI assistants a concise, curated Markdown map of a site's key pages, similar in spirit to robots.txt for crawl rules. Its absence isn't penalized by search engines, but it's a low-cost signal several answer engines are starting to look for.
How to fix it & effect on score: Add a plain-text /llms.txt with an H1 site name, a one-line summary, and a linked list of your most important pages. Fixing this removes the 3 pts deduction from the AEO (Answer Engine Optimization) category score on the next scan.
aeo-toc-missing
Long page has no jump-to-section navigation
| Severity | Weight | Category |
|---|---|---|
| Low | 3 pts | AEO (Answer Engine Optimization) |
What triggers it & why it matters: The page has roughly N words across N sections but no linked table of contents (anchor links pointing at heading ids). Answer engines and readers both benefit from being able to jump straight to a relevant subsection instead of scanning the whole page.
How to fix it & effect on score: Add id attributes to your H2/H3 headings and a short linked table of contents near the top of long-form content. Fixing this removes the 3 pts deduction from the AEO (Answer Engine Optimization) category score on the next scan.
aeo-speakable-missing
No Speakable schema for voice assistants
| Severity | Weight | Category |
|---|---|---|
| Low | 2 pts | AEO (Answer Engine Optimization) |
What triggers it & why it matters: The page has FAQ/QA/HowTo schema but no SpeakableSpecification marking which sections are suitable for text-to-speech playback by voice assistants. This is an optional enhancement, not a ranking requirement.
How to fix it & effect on score: Add a "speakable": { "@type": "SpeakableSpecification", "cssSelector": [...] } property to your WebPage/Article JSON-LD pointing at the summary or answer sections. Fixing this removes the 2 pts deduction from the AEO (Answer Engine Optimization) category score on the next scan.
aeo-ai-crawler-firewall
AI crawlers (tested as OAI-SearchBot) get the same page as visitors
| Severity | Weight | Category |
|---|---|---|
| Positive signal | 0 pts | AEO (Answer Engine Optimization) |
What it means: A request as OAI-SearchBot got the same page as a browser: no firewall, challenge or reduced content.
Evidence: measured on the live site at scan time.
aeo-ai-crawlers
AI search crawlers (OAI-SearchBot, PerplexityBot, Claude-SearchBot, etc.) are allowed
| Severity | Weight | Category |
|---|---|---|
| Positive signal | 0 pts | AEO (Answer Engine Optimization) |
What it means: No AI search or browsing crawler is disallowed in robots.txt.
Evidence: official requirement (documented by the engine or standard).
aeo-answer-schema
Page uses FAQPage/QAPage/HowTo structured data that answer engines can lift directly
| Severity | Weight | Category |
|---|---|---|
| Positive signal | 0 pts | AEO (Answer Engine Optimization) |
What triggers it & why it matters: This rule only ever surfaces as a passing signal in the current source — it fires (as a pass) when: Page uses FAQPage/QAPage/HowTo structured data that answer engines can lift directly. There is no separate failing issue() call under this exact id; the failure condition is the logical negation of the pass condition, and in most cases is covered by a related rule id documented elsewhere in this category (see the table above for a sibling rule on the same feature).
Effect on score: Meeting this condition costs nothing and confirms a positive signal. Missing it doesn't directly deduct points under this id — it typically shows up as a deduction under the related failing rule instead.
aeo-author
Page identifies an author or byline
| Severity | Weight | Category |
|---|---|---|
| Positive signal | 0 pts | AEO (Answer Engine Optimization) |
What triggers it & why it matters: This rule only ever surfaces as a passing signal in the current source — it fires (as a pass) when: Page identifies an author or byline. There is no separate failing issue() call under this exact id; the failure condition is the logical negation of the pass condition, and in most cases is covered by a related rule id documented elsewhere in this category (see the table above for a sibling rule on the same feature).
Effect on score: Meeting this condition costs nothing and confirms a positive signal. Missing it doesn't directly deduct points under this id — it typically shows up as a deduction under the related failing rule instead.
aeo-freshness
Page exposes a publish or last-updated date
| Severity | Weight | Category |
|---|---|---|
| Positive signal | 0 pts | AEO (Answer Engine Optimization) |
What triggers it & why it matters: This rule only ever surfaces as a passing signal in the current source — it fires (as a pass) when: Page exposes a publish or last-updated date. There is no separate failing issue() call under this exact id; the failure condition is the logical negation of the pass condition, and in most cases is covered by a related rule id documented elsewhere in this category (see the table above for a sibling rule on the same feature).
Effect on score: Meeting this condition costs nothing and confirms a positive signal. Missing it doesn't directly deduct points under this id — it typically shows up as a deduction under the related failing rule instead.
aeo-llms-txt
llms.txt follows the standard structure
| Severity | Weight | Category |
|---|---|---|
| Positive signal | 0 pts | AEO (Answer Engine Optimization) |
What it means: /llms.txt is a text file with an H1 title, a summary, sections and links to key pages.
Evidence: official requirement (documented by the engine or standard).
aeo-speakable
Page marks speakable sections for voice assistants
| Severity | Weight | Category |
|---|---|---|
| Positive signal | 0 pts | AEO (Answer Engine Optimization) |
What triggers it & why it matters: This rule only ever surfaces as a passing signal in the current source — it fires (as a pass) when: Page marks speakable sections for voice assistants. There is no separate failing issue() call under this exact id; the failure condition is the logical negation of the pass condition, and in most cases is covered by a related rule id documented elsewhere in this category (see the table above for a sibling rule on the same feature).
Effect on score: Meeting this condition costs nothing and confirms a positive signal. Missing it doesn't directly deduct points under this id — it typically shows up as a deduction under the related failing rule instead.
aeo-toc
Long-form content includes a jump-to-section table of contents
| Severity | Weight | Category |
|---|---|---|
| Positive signal | 0 pts | AEO (Answer Engine Optimization) |
What triggers it & why it matters: This rule only ever surfaces as a passing signal in the current source — it fires (as a pass) when: Long-form content includes a jump-to-section table of contents. There is no separate failing issue() call under this exact id; the failure condition is the logical negation of the pass condition, and in most cases is covered by a related rule id documented elsewhere in this category (see the table above for a sibling rule on the same feature).
Effect on score: Meeting this condition costs nothing and confirms a positive signal. Missing it doesn't directly deduct points under this id — it typically shows up as a deduction under the related failing rule instead.
aeo-ai-training-blocked
robots.txt opts out of AI training (N crawlers)
| Severity | Weight | Category |
|---|---|---|
| Informational | 1 pts | AEO (Answer Engine Optimization) |
What triggers it & why it matters: Training crawlers (GPTBot, ClaudeBot, Google-Extended, Applebot-Extended, CCBot, Bytespider, Meta-ExternalAgent) are disallowed. That is a legitimate choice and doesn't stop assistants citing the site; models may simply know less about the brand. Google-Extended also governs Gemini's grounding. Google AI Overviews use ordinary Googlebot.
How to fix it & effect on score: No change needed if the opt-out is intentional. Fixing this removes the 1 pts deduction from the AEO (Answer Engine Optimization) category score on the next scan.
Evidence: official requirement (documented by the engine or standard).
aeo-ai-crawler-challenged
AI crawlers get a bot-check page instead of the content
| Severity | Weight | Category |
|---|---|---|
| High | 10 pts | AEO (Answer Engine Optimization) |
What triggers it & why it matters: Requested as OAI-SearchBot the page returns a bot-verification (challenge/CAPTCHA) page, while a browser gets the real content. Crawlers can't solve the check, so engines see nothing to cite. Gate: while this fails, the category score is capped at 40, so strengths elsewhere can't hide it.
How to fix it & effect on score: Exempt verified AI search crawlers from the bot challenge, or lower the challenge level for them. Fixing this removes the 10 pts deduction from the AEO (Answer Engine Optimization) category score on the next scan.
Evidence: measured on the live site at scan time.
aeo-ai-crawler-content-differs
AI crawlers get much less content than visitors
| Severity | Weight | Category |
|---|---|---|
| Medium | 6 pts | AEO (Answer Engine Optimization) |
What triggers it & why it matters: The page served to OAI-SearchBot has less than half the words a browser gets. Engines may cite an incomplete version or skip it. A deliberate Markdown version (content-type text/markdown) is not flagged; see aeo-ai-markdown.
How to fix it & effect on score: Serve AI search crawlers the same content as visitors; check bot-specific rendering and CDN rules that vary content by user-agent. Fixing this removes the 6 pts deduction from the AEO (Answer Engine Optimization) category score on the next scan.
Evidence: measured on the live site at scan time.
aeo-llms-txt-invalid
/llms.txt returns a web page, not a text file
| Severity | Weight | Category |
|---|---|---|
| Low | 3 pts | AEO (Answer Engine Optimization) |
What triggers it & why it matters: The server answers /llms.txt with an HTML page, usually a catch-all route serving the site for any URL. Tools looking for llms.txt get HTML instead of a site map, so it counts as missing.
How to fix it & effect on score: Serve a real plain-text or Markdown /llms.txt. Fixing this removes the 3 pts deduction from the AEO (Answer Engine Optimization) category score on the next scan.
Evidence: deterministic check of the page or its markup.
aeo-llms-txt-incomplete
llms.txt is missing parts of the standard structure
| Severity | Weight | Category |
|---|---|---|
| Informational | 1 pts | AEO (Answer Engine Optimization) |
What triggers it & why it matters: The file exists but lacks part of the llms.txt format (llmstxt.org): an H1 title as the first line, a "> " summary, "## " sections, or at least three links to key pages.
How to fix it & effect on score: Use: "# Site name", "> one-line summary", then "## Section" headings with "- Page: note" links. Fixing this removes the 1 pts deduction from the AEO (Answer Engine Optimization) category score on the next scan.
Evidence: official requirement (documented by the engine or standard).
aeo-faq-schema-mismatch
FAQ structured data lists questions that aren't on the page
| Severity | Weight | Category |
|---|---|---|
| Medium | 6 pts | AEO (Answer Engine Optimization) |
What triggers it & why it matters: More than half the FAQPage questions can't be found in the visible page. Google's structured-data policy forbids marking up content users can't see, and AI engines may quote answers the page doesn't show. (FAQ schema is now only recommended for question headings that have an answer beneath them.)
How to fix it & effect on score: Show the FAQ on the page with the same questions and answers, or remove the hidden ones from the markup. Fixing this removes the 6 pts deduction from the AEO (Answer Engine Optimization) category score on the next scan.
Evidence: official requirement (documented by the engine or standard).
aeo-ai-markdown
AI crawlers get a Markdown version of the page
| Severity | Weight | Category |
|---|---|---|
| Positive signal | 0 pts | AEO (Answer Engine Optimization) |
What it means: The server answers AI crawlers with a lean Markdown version of the page (content-type text/markdown), which is easy for them to read and quote.
Evidence: measured on the live site at scan time.