Rules · geo/*
AI search rules
Generative-engine optimisation: whether AI crawlers that don't run JavaScript see the same content, valid and visible JSON-LD, an explicit AI robots policy, llms.txt, Markdown mirrors and answer-first writing.
$ void geo41 rules9 error · 14 warn · 18 infoupdated 16 Sept 2026
- geo/js-dependencyerrorMain content only appears after JavaScript runsOpenAI, Anthropic, Perplexity, Meta and ByteDance crawlers fetch HTML without executing JavaScript, so client-rendered text doesn't exist for them. Measured as 1 − (5-word shingles of rendered main text found in raw HTML fetched as GPTBot); above 0.20 is a scoring gate.
- geo/hidden-streamed-contentwarnCrawlers receive main content only inside hidden streaming containersWith Suspense on request-time routes, Next.js sends the shell first and the resolved content later in <div hidden id="S:n"> plus a script that moves it. Non-rendering crawlers get it out of reading order and inside a hidden element.
- geo/ai-bot-blockederrorAI crawler user agents get 401/403/429/503 or a challenge pageA WAF or bot-management rule that blocks GPTBot, OAI-SearchBot, ClaudeBot or PerplexityBot removes the site from AI answers regardless of robots.txt. Challenge responses to spoofed UAs can be inconclusive, because verified crawlers are identified by IP.
- geo/ai-content-differswarnAI crawlers get materially different HTML than browsersServing bots different text is either accidental (a UA-sniffing bot wall, a degraded variant) or cloaking; both mean AI answers are built from content users don't see.
- geo/jsonld-parse-errorerrorJSON-LD block is not valid JSONParsers discard the whole block, so the page loses every entity, breadcrumb and article signal in it. This is a scoring gate.
- geo/jsonld-unsafeerrorJSON-LD contains a literal </script or <!--User or CMS content containing </script> ends the script element early; that breaks the JSON and is an XSS vector. The Next.js JSON-LD guide requires escaping <.
- geo/jsonld-missinginfoPage has no JSON-LDStructured data makes entities, authorship, dates and breadcrumbs explicit for Google features and for systems that extract facts. Google says it isn't required for AI features, so this is informational.
- geo/jsonld-not-in-rawerrorJSON-LD is injected by JavaScriptNon-Google crawlers never run the script that injects the markup, and Google warns JS-generated Product markup makes Shopping crawls less frequent and less reliable.
- geo/home-entity-missingwarnHome page lacks Organization + a single WebSite nodeGoogle's site name system reads WebSite from the home page, and Organization supplies logo, sameAs and the canonical brand entity that other pages reference by @id.
- geo/jsonld-schemaerrorJSON-LD @context isn't schema.org or @type isn't a schema.org typeConsumers match on schema.org types; a wrong @context or a misspelled @type ("BlogPost", "Organisation") makes the node meaningless.
- geo/jsonld-requirederrorStructured data type is missing Google-required propertiesWithout the required properties (WebSite name/url, BreadcrumbList items, Product offers/review/rating, SoftwareApplication offers.price plus aggregateRating or review, ProfilePage mainEntity, VideoObject name/thumbnailUrl/uploadDate) the page isn't eligible for the feature.
- geo/jsonld-recommendedinfoStructured data missing recommended propertiesArticle headline/image/datePublished/author, Organization url/logo, and Product image/currency/availability improve eligibility and entity understanding.
- geo/jsonld-dateswarnStructured data dates are invalid, lack a timezone, or modified < publishedGoogle asks for ISO 8601 dates with a timezone; ambiguous or inconsistent dates weaken freshness signals that Bing and AI engines use.
- geo/breadcrumb-invalidwarnBreadcrumbList positions, names or item URLs are invalidBreadcrumb rich results need ≥ 2 ListItems with positions starting at 1, a name, and absolute item URLs (the last item may omit item).
- geo/faq-deprecatedinfoFAQPage/HowTo/SearchAction markup no longer produces rich resultsFAQ rich results stopped showing on 2026-05-07, HowTo was removed in 2023 and the sitelinks search box in November 2024. The markup is harmless but earns nothing.
- geo/jsonld-id-unresolvedwarnJSON-LD @id references don't resolveA {"@id": …} reference that matches no node on the page or the home page graph leaves publisher/author links dangling; relative @ids resolve inconsistently.
- geo/jsonld-not-visiblewarnStructured data values don't appear on the pageGoogle's structured data policies forbid marking up content that isn't visible to readers; ratings or headlines that exist only in JSON-LD can trigger manual actions.
- geo/entity-name-mismatchinfoBrand name differs across og:site_name, JSON-LD and titleConsistent entity naming helps search engines and LLMs merge mentions into one entity (Bing: consistent entities; Google site names).
- geo/article-date-missingwarnArticle has no machine-readable or visible dateFreshness is a selection signal for Bing/Copilot and answer engines; Google wants datePublished/dateModified plus a visible date that matches.
- geo/article-author-missingwarnArticle author missing or malformedGoogle's article guidance wants author as a Person/Organization with a name and a profile url or sameAs; string authors or "Posted by …" names are ambiguous entities.
- geo/landmarkswarnMissing <main>, <nav> or <article> landmarksMarkdown converters (Cloudflare Markdown for Agents, reader modes), agents and screen readers use landmarks to separate main content from navigation and boilerplate.
- geo/thin-contentinfoArticle main content under 150 wordsVery short pages rarely contain a citable answer and may be treated as thin. This is a heuristic and doesn't apply to tools or app pages.
- geo/answer-firstinfoOpening paragraph doesn't state the answer conciselyMicrosoft's guidance for AI answers favours one- to two-sentence, self-contained answers that name the subject; paragraphs opening with "It/This" can't be lifted on their own.
- geo/no-citationsinfoLong content with no outbound links to sourcesIn the GEO study (KDD 2024), adding citations was among the most effective methods (+115% visibility for rank-5 sources). Citations also help readers verify claims.
- geo/no-statisticsinfoLong content with no quantified factsStatistics addition raised generative-engine visibility by about 30–40% in the GEO study, and high-influence cited pages are rich in numerical facts.
- geo/unstructured-contentinfoLong content with no lists, tables or subheadingsBing and Microsoft guidance cite clear headings, lists and tables as what AI systems parse and reuse; walls of prose are hard to chunk.
- geo/wall-of-textinfoParagraphs longer than 150 wordsLong paragraphs bury answers; Microsoft lists walls of text among patterns that reduce inclusion in AI answers.
- geo/vague-headingsinfoGeneric section headings ("Overview", "More", "Details")Headings are how engines and agents label sections; topic or question headings ("How much does Acme cost?") can be matched to queries and lifted with their answer.
- geo/markdown-alternateinfoNo working Markdown alternate for this content pagellms.txt v2 recommends per-page Markdown mirrors advertised with <link rel="alternate" type="text/markdown">; coding agents fetch them instead of parsing HTML. An advertised mirror that 404s or serves HTML is a warning.
- geo/markdown-mirror-indexablewarnMarkdown mirror can compete with the HTML page, or diverges from itWithout X-Robots-Tag: noindex or a canonical Link header, .md mirrors can be indexed as duplicates; mirrors carrying different facts than the HTML risk looking like cloaking.
- geo/markdown-negotiation-varywarnAccept: text/markdown negotiation without Vary: AcceptIf the same URL serves HTML or Markdown depending on Accept, both responses need Vary: Accept, or a CDN can cache Markdown and serve it to browsers. Next.js 16.3.5 overwrites a custom Vary on prerendered HTML responses (verified).
- geo/markdown-negotiationinfoNo Markdown response for Accept: text/markdownCoding agents (Claude Code, Cursor) request text/markdown; nextjs.org and Cloudflare's Markdown for Agents answer with Markdown. It's optional and not a ranking factor.
- geo/llms-txt-missinginfoNo /llms.txtllms.txt is a curated Markdown index for inference-time agents, used mostly by coding agents. Adoption is cheap but evidence of answer-engine use is thin (97% of files got zero requests in Ahrefs' 2026 study), so this is informational.
- geo/llms-txt-errorerror/llms.txt returns a server errorA 5xx fails Lighthouse's agentic-browsing llms-txt audit (a 404 counts as not applicable) and signals a broken route.
- geo/llms-txt-invalidwarn/llms.txt doesn't follow the llms.txt formatThe spec requires an H1 as the first line, then an optional > summary, then ## sections of - [name](url): notes links. Lighthouse checks for the H1, a link and a length of at least 50.
- geo/llms-txt-broken-linkswarn/llms.txt links to URLs that failAgents follow llms.txt links directly; 404s waste their context and tool calls.
- geo/llms-txt-not-linkedinfollms.txt exists but isn't linked from the home pagellms.txt v2 adds <link rel="describedby" href="/llms.txt"> so agents can discover it from any page.
- geo/robots-ai-policyinfoAI crawler policy (allow/deny matrix from robots.txt)Training crawlers (GPTBot, ClaudeBot, Google-Extended, CCBot…) and retrieval crawlers (OAI-SearchBot, Claude-SearchBot, PerplexityBot) are separate tokens; an explicit policy controls each independently. A bot named in its own group ignores the * group.
- geo/search-bots-blockederrorrobots.txt blocks AI search or user-triggered fetchersOpenAI: sites opted out of OAI-SearchBot aren't shown in ChatGPT search answers. The same applies to Claude-SearchBot and PerplexityBot. Blocking user fetchers (ChatGPT-User, Claude-User) stops assistants opening pages a user asks about (warning).
- geo/training-bots-blockedinforobots.txt blocks AI training crawlersA legitimate choice: it doesn't affect Google Search or AI Overviews (Google-Extended doesn't), or AI search visibility while retrieval bots stay allowed.
- geo/content-signalinfoNo Content-Signal usage preferencesContent-Signal (search, ai-input, ai-train), from Cloudflare and aligned with the IETF AIPREF draft, states how content may be used beyond crawl permission. It's an emerging, non-binding signal.