AEO NIUEXA

Technical & Foundational Health

15% Weight Check reference Priorities vary by result

Technical checks look at whether search engines and AI crawlers can reach, read and index your pages: robots.txt, sitemaps, status codes, canonical tags, indexing directives, HTTPS, server headers and page speed. If crawlers cannot open a page, or are told not to index it, nothing else on the page can help it appear in search results or AI answers.

Access and indexing first: Fix Site Crawlability, robots.txt, noindex settings (X-Robots-Tag and Snippet Controls), Soft 404 and Canonical Target problems before the other technical checks. The checks after them cannot help a page that crawlers cannot open or are told not to index.
Our scanner is not the crawler: We test from our own servers. When a firewall, CDN or bot challenge refuses our requests (HTTP 401, 403, 407 or 429, or a challenge page), the checks that depend on them, such as Site Crawlability, robots.txt Validation, Sitemap Validation and Canonical Target, say "could not test" instead of failing, and links we could not verify are not counted as broken. What our scanner gets says nothing about what Googlebot or an AI crawler gets: your server logs and the free access check help there.
How these checks count: A check counts by its importance in this dimension multiplied by how well the evidence supports it: Official and Corroborated checks count in full, Practitioner advice counts at half weight, and checks marked Unproven are shown in your report but not scored. A check that is N/A, not measured or "could not test" is left out of the score rather than counted as a pass or a failure; if nothing in this dimension can be weighed, the dimension is shown as not measured and the other weights are scaled up. The badge next to each check shows the usual priority of a failure; your report shows the priority of your own result. See the scoring system for the details.

Crawlability Checks

Whether crawlers can reach your site, read your rules and your sitemap, and follow your links

robots.txt Validation and AI Bot Permissions

Critical
What it checks
Two checks read your robots.txt. robots.txt Validation checks that the file exists, can be read, has User-agent lines and names your sitemap. AI Bot Permissions, which counts in the AI-Specific dimension, reads the rules the way crawlers do (RFC 9309) and judges each AI crawler on the page that was scanned, grouped by purpose: search (OAI-SearchBot, PerplexityBot, Claude-SearchBot, Bingbot, Googlebot), user fetch (ChatGPT-User, Perplexity-User, Claude-User) and training (GPTBot, ClaudeBot, CCBot, Google-Extended, Applebot-Extended, Bytespider, meta-externalagent). Crawler names as of 2026-10-07.
Why it matters
robots.txt tells crawlers which paths they may visit and where your sitemap is. Search and user-fetch crawlers decide whether AI search and assistants can open a page, so blocking one on a page you want found is a real problem. Training crawlers are a separate decision: blocking GPTBot or Google-Extended is your policy choice and does not hide the page from AI search. A crawler with no group of its own follows your User-agent: * rules, so you do not need an Allow line for every bot.
How it is scored
Both checks rest on Official evidence and count in full. robots.txt Validation: 100 for a readable file with User-agent lines and a Sitemap line, 80 (still a pass) without the Sitemap line, 50 (fail) without User-agent lines, which is also what an HTML page served instead of rules gets, and 0 (fail) when the file is missing (404) or answers with another error. When a firewall refuses our request (401, 403, 407 or 429, also with a browser User-Agent) or the server does not answer, the result is "could not test" and it is left out of the score. AI Bot Permissions: 100 when no search or user-fetch crawler is blocked on the page (training blocks are fine). It fails with 0 when every search crawler is blocked, 25 when some are, and 50 when only user-fetch crawlers are blocked. A missing robots.txt (404 or another 4xx) lets every crawler in. If robots.txt cannot be read (a firewall refusal, a server error, no answer or an HTML page instead of rules) the check is not measured and left out of the score.
Pass: a readable robots.txt with User-agent lines, and no search or user-fetch crawler blocked on the page Not measured or could not test: robots.txt could not be read Fail: no robots.txt or no User-agent lines, or a search or user-fetch crawler blocked on the page
How to fix
Put the file at the root of your domain (e.g., example.com/robots.txt), with at least one User-agent group and a Sitemap line. Give a blocked search or user-fetch crawler its own group with Allow: /, or remove the rule that blocks it, and repeat your private-path Disallow lines in that group (a named group does not inherit the * rules). Decide training access separately. The AI-Specific check reference covers AI Bot Permissions in full.
Example
# robots.txt - allow AI search, decline training (example policy)
User-agent: OAI-SearchBot
User-agent: Claude-SearchBot
User-agent: PerplexityBot
Allow: /
Disallow: /admin/

User-agent: GPTBot
User-agent: ClaudeBot
User-agent: CCBot
User-agent: Google-Extended
Disallow: /

User-agent: *
Allow: /
Disallow: /admin/

Sitemap: https://example.com/sitemap.xml

Sitemap Validation

High
What it checks
Looks for your sitemap at the standard addresses (/sitemap.xml, /sitemap_index.xml, /sitemap-index.xml, /wp-sitemap.xml, /sitemap.xml.gz and /sitemap_index.xml.gz) and, when none of them has one, at the sitemaps declared in robots.txt. Only a real sitemap counts: an XML urlset or sitemap index (compressed files are read) or a plain-text list of URLs. An HTML page answered at that address is not a sitemap. For a sitemap index it reads up to 10 child sitemaps. priority and changefreq are not scored, because Google ignores them.
Why it matters
A sitemap is the list of pages you tell search engines you want found. It helps discovery; it does not guarantee that a page is indexed.
How it is scored
Official evidence, counts in full. 100 for a sitemap that lists URLs. 20 (fail) when a sitemap answers but lists no URLs. 0 (fail) when no sitemap is found. When no sitemap is found and one of the addresses we tried refused our request (401, 403, 407 or 429), answered with a server error or did not answer, the result is "could not test" and it is left out of the score; only a clean "not found" everywhere fails. Search Console's Sitemaps report shows what Google itself gets.
Pass: a sitemap that lists URLs Fail: no sitemap found, or a sitemap that lists no URLs Could not test: our requests were refused, failed or got no answer
How to fix
Create an XML sitemap at /sitemap.xml listing the canonical address of every page you want found, with a lastmod that changes only when the content does. Declare it in robots.txt with a Sitemap line and submit it in Google Search Console and Bing Webmaster Tools.
Example
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://example.com/</loc>
    <lastmod>2024-01-15</lastmod>
  </url>
  <url>
    <loc>https://example.com/about</loc>
    <lastmod>2024-01-10</lastmod>
  </url>
</urlset>

Sitemap Membership

Medium
What it checks
Looks the scanned page up in the sitemaps we read: the sitemap at a standard location or declared in robots.txt, its child sitemaps (up to 10) and the other sitemaps robots.txt declares on the same site, up to 50,000 URLs in all. The page's own address, the address it lands on after redirects and its canonical all count.
Why it matters
Your sitemap is the list of pages you tell search engines you want found. A page missing from it is harder to discover, and a sitemap that leaves out real pages is not a truthful list.
How it is scored
Official evidence, counts in full. 100 when the page is listed. 0 (fail) when the sitemaps were read in full and the page is not in them. When part of the sitemaps could not be read (more child sitemaps than we read, a file cut at the size limit, a sitemap on another host, more than 50,000 URLs), a page we did not find is "could not test", never "not listed".
Pass: the page or its canonical is listed Fail: sitemaps read in full, page not listed N/A: no sitemap, an empty or unreadable sitemap, a sitemap only partly read (could not test), or a noindex page
How to fix
Add the page's canonical address to your sitemap. Better, generate the sitemap from the same list of canonical, indexable pages your site publishes, so new pages are added and retired ones removed automatically.

Site Crawlability

Critical
What it checks
Whether your home page answers our request normally and robots.txt does not block every crawler. A server error or no answer is tried a second time, with a browser User-Agent, before it counts. When a firewall, CDN or bot challenge refuses our scanner, the result is “could not test”: our request is not a real crawler’s, so it shows nothing about what Googlebot or AI crawlers get.
Why it matters
Crawlers that get an error, no answer or a blanket robots.txt block cannot read the site, so search engines and AI answers cannot use it.
How it is scored
Official evidence, counts in full. 100 for a normal answer (HTTP 200). 0 (Critical) for a server error on both attempts, or for a robots.txt that blocks every crawler from the whole site (Disallow: / for all user agents), even when our own request was refused. 50 for another status, such as a 404. 20 when the site does not answer (a timeout or connection error on both attempts, or a domain that does not resolve). A refusal of our scanner (401, 403, 407, 429 or a bot-challenge page) is "could not test": left out of the score.
Pass: HTTP 200 and robots.txt lets at least one crawler in Fail: 5xx, another error status, no answer, or robots.txt blocks everyone Could not test: our scanner was refused by a firewall, CDN or bot challenge
How to fix
Fix server errors and slow answers, and keep robots.txt open to the crawlers you want. If our scanner was refused, check your firewall’s bot settings and your server logs to see what verified crawlers get, or run the free access check.

JS Rendering

High
What it checks
Reads the page's HTML for JavaScript frameworks and for signs of how the page is built: server or static rendering markers (such as Next.js page data, Nuxt state, Vue server rendering, Angular Universal state, SvelteKit, Gatsby or Astro), an almost empty root container (a div with the id root, app or main holding fewer than 50 characters of text), loading placeholders (spinner or skeleton classes) and more than three script bundles.
Why it matters
Some AI crawlers may not run JavaScript, so content that appears only after scripts run can be missing for them. Google renders JavaScript, but later and not always completely.
How it is scored
Official evidence, counts in full. 100 when no JavaScript framework is detected, 90 when server or static rendering is detected, 70 for a framework with no sign of server rendering, and 40 when the page looks rendered in the browser (an almost empty root container, or loading placeholders together with many script bundles). It then loses 20 for an almost empty root container and 10 for more than three script bundles.
Pass: no sign of browser-only rendering Fail: an almost empty root container, or a page rendered in the browser N/A: no HTML to read
How to fix
Serve the main content in the initial HTML: use server-side rendering or static generation (for example Next.js, Nuxt or Angular SSR), or pre-render your key pages. Open the page with View Source (not the element inspector) and check that your main text is there.

Redirect Chain

Medium
What it checks
Follows the page's own address to its final one (how many redirects, permanent 301/308 or temporary 302/303/307, loops, an http-to-https upgrade) and, using the link check described under Broken Links, flags links on the page that reach their destination only through two or more redirects.
Why it matters
Each redirect adds a round trip before the page loads. Long chains slow visitors down, and crawlers stop following after a number of hops.
How it is scored
Practitioner advice, counts at half weight. Starts at 100 and loses 15 for each redirect after the second, 10 for each temporary redirect and 50 for a loop; a single http-to-https redirect gets 10 back (up to 100). Each link on the page that needs two or more redirects costs 10 more, at most 30. It fails with a loop, more than five redirects or a score under 60 (High; Critical for a loop), or when a link needs two or more redirects (Medium).
Pass: a short chain and no link that needs two or more redirects Fail: a loop, a long chain, or links that need two or more redirects N/A: neither the page's redirects nor its links could be measured
How to fix
Point every redirect and internal link straight at the final address, so each takes one step at most. Use 301 for permanent moves. Fix redirect loops.

Indexation Checks

Whether search engines may index the page, show its text and keep the address you want

Google Index Status

High
What it checks
Runs a Google site: search for your domain (the first 10 results) and reports whether pages come back, with Google’s own result estimate when there is one. It is a rough sample, not an index count.
Why it matters
Google’s AI features, such as AI Overviews and AI Mode, can only use pages that are in Google’s index.
How it is scored
Official evidence, counts in full. 100 when Google estimates more than 100 results, 85 for a full first page of results (or an estimate between 11 and 100), 75 for fewer. 0 (High) when the site: search returns nothing: confirm it in Search Console before acting, because a site: search is only a sample. When the search lookup fails or gives no usable answer, the check is "not measured" and left out of the score; we never guess a page count.
Pass: the site: search returns pages Fail: no pages returned Not measured: no usable search answer
How to fix
Check your key pages with URL Inspection in Google Search Console. Submit your sitemap there and make sure robots.txt and noindex settings let Googlebot in.

Bing Index Status

Not scored
What it checks
Reminds you to confirm in Bing Webmaster Tools that your pages are in Bing. It is not checked automatically.
Why it matters
Bing’s index feeds Bing search and the AI answers Microsoft builds on it.
How it is scored
Not scored: there is no Bing search API to check it automatically, so it is always N/A and left out of the score.
How to fix
Register in Bing Webmaster Tools, verify the site, submit your sitemap and check the indexing and crawl-error reports. Make sure robots.txt lets Bingbot in.

Canonical URL

High
What it checks
Looks for the page's canonical: a link rel="canonical" tag in the HTML, or a canonical in the HTTP Link header. It checks that there is only one tag, that the address is absolute and uses the page's protocol, and whether it names this page, another page on the same site or another domain.
Why it matters
A canonical URL tells search engines which address to keep when the same content is reachable at several. Without one, they pick for themselves and may keep the wrong address.
How it is scored
Official evidence, counts in full. Starts at 100 and loses 40 for more than one canonical tag, 20 for a canonical that names another page on the same site, 20 for a relative address and 20 for a different protocol (http instead of https, or the reverse). It passes at 70 or more with a single tag, so one of these problems alone still passes. 0 (High) when there is no canonical. A canonical on another domain is allowed. Whether the address works is checked by Canonical Target below.
Pass: one canonical with at most one of these problems Fail: no canonical, more than one tag, or two or more problems
How to fix
Add one canonical link tag to each page's head, with the full https:// address of the page itself, or of the preferred version when the same content is published at several addresses.
Example
<head>
  <link rel="canonical" href="https://example.com/page-url">
</head>

Canonical Target

High
What it checks
Opens the canonical URL your page declares (its canonical link tag, else the Link header) when it names another page, without following redirects, and checks that it answers HTTP 200 directly, without a redirect, an error or a noindex directive in its header or robots meta tag. A canonical that is the page itself needs no test, and one that differs from the page only by a trailing slash counts as the page itself unless it redirects.
Why it matters
The canonical tells search engines which address to keep. If that address redirects, is broken or is marked noindex, you are pointing them at a page they cannot use, and they may ignore your preference or drop the page.
How it is scored
Official evidence, counts in full. 100 when the canonical opens directly with 200 and may be indexed. 0 when it redirects (High), returns an error (Critical for 404 and 410, High for other errors), answers with another status than 200 (Medium), is marked noindex (Critical) or is not a web address (High).
Pass: the canonical opens directly (HTTP 200) and may be indexed Fail: redirect, error status or noindex N/A: no canonical, the canonical is the page itself, or we could not test (timeout, refusal, bot challenge)
How to fix
Make the canonical the full, final https:// address of a live page, usually the page's own address. Find where the value comes from (page setting, template, CMS default or plugin), fix it there, clear caches and re-scan.

Soft 404

High
What it checks
Looks for a page that answers with a success status but shows a "page not found" message: a title or main heading such as "Page not found", "404 | Shop" or "Pagina non trovata" on a short page (1,500 characters of visible text or fewer), or a page-specific phrase such as "this page does not exist" on an almost empty page (500 characters or fewer). English and Italian wording is recognised, with more Italian wording on Italian pages. A bare "404" elsewhere ("Peugeot 404 for sale") or a heading about the error ("How to fix 404 errors") does not count.
Why it matters
Search engines treat these pages as error pages, or index the error text as if it were your content. Honest status codes keep missing pages out of results and real pages in.
How it is scored
Official evidence, counts in full. 100 when the page's content matches its success status. 0 (High) when it says it was not found. Not applicable when the page did not answer with a 2xx status.
Pass: no "not found" message on a page that answered 200 Fail: "not found" message on a page that answered 200 N/A: the page did not answer with a success status
How to fix
If the page is gone, make the server answer 404 (or 410 when removed for good). If it should exist, restore its content, or redirect it to a real equivalent page, not to the home page.

X-Robots-Tag

Critical
What it checks
Reads the X-Robots-Tag HTTP header of the page for noindex, none and nofollow directives that apply to every crawler, to Googlebot or to Bingbot. Directives aimed only at other crawlers are listed but do not count, and other values, such as noarchive, do not change the score.
Why it matters
An X-Robots-Tag header can keep a page out of search results at the server level, even when the page looks fine in a browser. A noindex directive prevents indexing. Robots meta tags and the other snippet controls are scored by Snippet Controls below, so the same noindex is not counted twice.
How it is scored
Official evidence, counts in full. 100 when the header is absent or blocks nothing. 50 (fail, High) for nofollow. 30 (fail, Critical) for noindex or none.
Pass: no noindex, none or nofollow for Google, Bing or all crawlers Fail: nofollow (50) Fail: noindex or none (30)
How to fix
Remove noindex, none or nofollow from the X-Robots-Tag header in your server or CDN settings for pages you want found in search and AI answers. Look at the response headers with curl -I or your browser's developer tools.

Snippet Controls

Critical
What it checks
Reads the robots, googlebot and bingbot meta tags and the X-Robots-Tag header for noindex, nosnippet, max-snippet:0 and none, and measures how much of the text is wrapped in data-nosnippet. A noindex sent only in the X-Robots-Tag header is scored by X-Robots-Tag, not here.
Why it matters
noindex keeps the page out of search results. nosnippet and max-snippet:0 stop search engines from showing its text, and Google applies them to its AI features too. data-nosnippet hides only the passages you mark; that is your choice.
How it is scored
Official evidence, counts in full. 100 when none of those directives is set for every crawler, Googlebot or Bingbot. 0 when one is (Critical for noindex or none, High for nosnippet or max-snippet:0). data-nosnippet never fails the check; when it covers more than half of the text, the report says so for information.
Pass: no noindex, nosnippet, max-snippet:0 or none Fail: one of them is set for Google, Bing or all crawlers
How to fix
Remove the directive from the page template and from server or CDN headers on pages that should appear in search and AI answers. Keep data-nosnippet for passages you really want kept out of snippets.

Security Checks

Secure connections and resources, for visitors and crawlers

HTTPS Security

Critical
What it checks
Opens the page. For an https:// address it checks that the secure connection works, so a certificate or connection error counts against it; for an http:// address it checks that the page ends up on https://.
Why it matters
Browsers warn visitors about pages without HTTPS, and a broken certificate stops visitors and crawlers from opening the page. Serving every page over HTTPS is standard practice.
How it is scored
Practitioner advice, counts at half weight. 100 when an https:// page opens, 95 when an http:// address redirects to https://. 50 (fail, Critical) when the https:// connection fails, for example on a certificate error. 0 (fail, Critical) when the page stays on http:// or cannot be opened.
Pass: the page opens over HTTPS Fail: certificate or connection error, or no HTTPS
How to fix
Install a certificate (free from Let's Encrypt or your host), redirect every HTTP address to HTTPS with a 301, and update internal links and resources to https://.

Mixed Content

Critical
What it checks
On an https:// page, looks for resources the HTML loads over plain http://: scripts, stylesheets, iframes, objects and form actions (active content), and images, video, audio and CSS url() backgrounds (passive content). Relative and protocol-relative addresses are fine.
Why it matters
Browsers block or warn about insecure files on a secure page, which can break images, scripts and styles for visitors.
How it is scored
Practitioner advice, counts at half weight. Starts at 100 and loses 25 for each active resource and 5 for each passive one. Any active mixed content fails the check (Critical); passive mixed content alone lowers the score but passes. A page served over http:// passes this check, because HTTPS Security covers it.
Pass: no mixed content Lower score: passive mixed content only Fail: a script, stylesheet, frame, object or form over http://
How to fix
Load every image, script, stylesheet and iframe over https://, and point forms at https:// addresses. Look for hard-coded http:// addresses in templates, content and plugin settings.

Content Security Policy

Retired
Status
Retired as a scored technical check: it has no effect on your score. The Security tab of a report still audits your Content Security Policy header for information.

Performance Checks

Speed and server settings. Compression, HTTP/2 Support and Cache Headers read the response headers of a request for the page. The separate Performance dimension scores the PageSpeed lab metrics in detail: see Performance checks.

Page Load Speed

High
What it checks
Runs a Google PageSpeed Insights lab test of the page and reads its performance score and three lab metrics: Largest Contentful Paint (LCP), Total Blocking Time (TBT) and Cumulative Layout Shift (CLS).
Why it matters
Faster pages serve visitors better and are part of Google's page experience signals. Speed is not a proven AI citation factor.
How it is scored
Corroborated evidence, counts in full. A metric is good when LCP is under 2.5 s, TBT under 300 ms and CLS under 0.1. 100 when all three are good and the performance score is 90 or more; 85 with at least two good and a score of 75 or more. Below that it fails: 70 with at least one good and a score of 50 or more (Medium), 50 for a score of 30 or more (High), 25 below that (Critical). When PageSpeed Insights is not available or gives no result, the check is not measured and left out of the score.
Pass: at least two good metrics and a PageSpeed score of 75 or more Fail: fewer good metrics or a lower PageSpeed score Not measured: no PageSpeed result
How to fix
Compress images and use modern formats such as WebP. Enable compression and browser caching, defer scripts that are not needed for the first view, and follow the specific suggestions in PageSpeed Insights.

Core Web Vitals

Not measured
What it checks
Reserved for real-visitor Core Web Vitals: Largest Contentful Paint (LCP), Interaction to Next Paint (INP) and Cumulative Layout Shift (CLS) from the Chrome UX Report. We do not measure them yet.
Why it matters
Core Web Vitals are Google's measures of loading, responsiveness and visual stability for real visitors, and part of its page experience signals. They are not a proven AI citation factor.
How it is scored
Not measured yet: the check is shown as not measured and left out of the score. It reports 0 (High) only when the page could not be crawled. Until real-visitor data is available, Page Load Speed above uses the lab limits our scanner checks: LCP under 2.5 s, CLS under 0.1, and TBT under 300 ms standing in for responsiveness.
How to fix
For LCP, make the largest image or text block load early. For INP, reduce JavaScript and break up long tasks. For CLS, give images and embeds fixed dimensions and don't insert content above what is already shown. Search Console's Core Web Vitals report and PageSpeed Insights show your real-visitor data.

Compression

High
What it checks
Reads the Content-Encoding header of the page's response: Brotli (br), gzip, deflate or Zstandard (zstd). Some hosts and CDNs (GitHub Pages, Vercel, Netlify, Cloudflare, AWS CloudFront) compress in a way the header may not show; we recognise them from their response headers.
Why it matters
Compressed HTML, CSS and JavaScript are much smaller to download, so pages load faster for visitors and crawlers.
How it is scored
Corroborated evidence, counts in full. 100 for Brotli, 90 for gzip, 80 for deflate or Zstandard, and 80 when one of those hosts or CDNs serves the page without showing the encoding. 0 (fail, High) when the response is not compressed.
Pass: Brotli, gzip, deflate or Zstandard, or a CDN that compresses Fail: no compression
How to fix
Enable Brotli or gzip compression in your web server configuration (nginx, Apache, IIS) or turn it on in your CDN.

HTTP/2 Support

Medium
What it checks
Checks which HTTP version served the page to our request and whether the Alt-Svc header advertises HTTP/2 (h2) or HTTP/3 (h3). The hosts and CDNs listed under Compression serve HTTP/2 even when our client does not see it; we recognise them from their response headers.
Why it matters
HTTP/2 and HTTP/3 let a browser fetch many files over one connection, which usually makes pages load faster for visitors. It is a speed practice, not a proven search or AI factor.
How it is scored
Practitioner advice, counts at half weight. 100 for HTTP/3, 90 for HTTP/2, 80 when one of those hosts or CDNs serves the page. 40 (fail, Medium) when only HTTP/1.1 is seen.
Pass: HTTP/2 or HTTP/3 Fail: HTTP/1.1 only
How to fix
Turn on HTTP/2 (and HTTP/3 if offered) in your web server or CDN settings; most hosts and CDNs support it. It needs HTTPS.

Resource Hints

Medium
What it checks
Looks for preconnect, dns-prefetch, preload, prefetch and modulepreload links in the page, and compares them with the other domains the page loads scripts, stylesheets and images from.
Why it matters
Hints such as preconnect and preload let the browser start fetching important files earlier, so the first view can appear sooner.
How it is scored
Corroborated evidence, counts in full. Starts at 50 and adds 15 for preconnect, 10 for dns-prefetch, 15 for preload, 5 for prefetch and 10 when at least 70% of the third-party domains have a hint. It loses 5 for each well-known third-party domain used without a hint (such as Google Fonts, Google Tag Manager or a public CDN) and 5 for each preload without an as attribute. It fails (Medium) only when the page loads files from other domains and has no hints at all.
Pass: at least one hint, or no files from other domains Fail: files from other domains and no hints
How to fix
Add preconnect for the third-party domains your page needs first (fonts, CDN), dns-prefetch for other external domains, and preload, with an as attribute, for critical files such as the main font.
Example
<head>
  <!-- Preconnect to critical origins -->
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://cdn.example.com" crossorigin>

  <!-- DNS prefetch for other domains -->
  <link rel="dns-prefetch" href="https://analytics.example.com">

  <!-- Preload critical resources -->
  <link rel="preload" href="/fonts/main.woff2" as="font" type="font/woff2" crossorigin>
</head>

Cache Headers

Medium
What it checks
Reads the caching headers of the page's response: Cache-Control and its max-age, ETag, Last-Modified and Expires.
Why it matters
Cache headers let browsers reuse files they already have, so repeat visits load faster and your server does less work.
How it is scored
Practitioner advice, counts at half weight. 40 for a Cache-Control header, 30 more for a max-age above zero, 10 more for a day or longer and 10 more for a week or longer; 10 for an ETag or Last-Modified header, plus 5 for each of the two (at most 100). It passes when Cache-Control is present and either allows caching (no no-store, no-cache or private) or comes with ETag or Last-Modified. Without Cache-Control it fails (Medium), except on GitHub Pages, where the host manages caching (60).
Pass: Cache-Control that allows caching, or that comes with ETag or Last-Modified Fail: no Cache-Control, or caching turned off with no ETag or Last-Modified
How to fix
Give versioned static files (images, CSS, JavaScript) a long Cache-Control max-age and HTML a short one, or no-cache with an ETag or Last-Modified header. Use versioned file names so updates reach visitors.

Compatibility Checks

Phones, languages and translated versions

Mobile Responsiveness

High
What it checks
Looks for a viewport meta tag and for an @media rule in the page's HTML. Media queries that live only in external stylesheets are not read, so such a page misses the media-query points.
Why it matters
Google indexes the mobile version of pages, and many visitors read on phones. A page that does not fit small screens is hard to use.
How it is scored
Practitioner advice, counts at half weight. 100 with a viewport meta tag and an @media rule; it loses 50 without the viewport tag and 25 without an @media rule. It passes at 75, so the viewport tag alone passes.
Pass: a viewport meta tag (100 with an @media rule, 75 without) Fail: no viewport meta tag N/A: no HTML to read
How to fix
Add the viewport meta tag to your head and use responsive CSS with media queries. Check the page on a real phone or in your browser's device view.
Example
<!-- Add to <head> -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<!-- CSS media queries -->
<style>
@media (max-width: 768px) {
  .container { padding: 10px; }
  .sidebar { display: none; }
}
</style>

Hreflang Tags

Medium
What it checks
Reads the hreflang annotations in link rel="alternate" tags and in the HTTP Link header. It checks the language and region codes (ISO 639-1 languages, ISO 3166 regions and script subtags such as zh-Hant), that the page lists itself, and that there is an x-default when there are several versions. It does not open the other versions to check that they link back.
Why it matters
Hreflang tells search engines which language or regional version of a page to show to which people, so they don't show the wrong one.
How it is scored
Official evidence, counts in full. Starts at 100 and loses 30 when the page does not list itself, 20 when several versions have no x-default, and 15 for each invalid code. It passes at 60 or more with no invalid code.
Pass: valid codes, with at most one of the two gaps (self-reference, x-default) Fail: an invalid code, or both a missing self-reference and a missing x-default N/A: no hreflang annotations (a single-language page)
How to fix
Add an alternate link with hreflang for every language version, including one for the page itself and an x-default for visitors whose language you do not serve. Every version should list all the others.
Example
<head>
  <link rel="alternate" hreflang="en" href="https://example.com/page">
  <link rel="alternate" hreflang="es" href="https://example.com/es/page">
  <link rel="alternate" hreflang="fr" href="https://example.com/fr/page">
  <link rel="alternate" hreflang="x-default" href="https://example.com/page">
</head>

Language Attribute

Medium
What it checks
Reads the lang attribute of the page's html element and checks that it is a well-formed language code, such as en, en-GB or it. On English and Italian pages it also compares it with the language of the text: lang="en" on a page written in Italian, or the reverse, counts as wrong.
Why it matters
Screen readers, browsers and other tools use the declared language to read and process the page. A missing or wrong value makes them read it with the wrong rules.
How it is scored
Official evidence, counts in full. 100 for a well-formed lang attribute, 70 (still a pass) when the value is not well formed, 50 (fail) when lang says English or Italian but the text is in the other language, 0 (fail) when there is no lang attribute.
Pass: a lang attribute that matches the text Fail: no lang attribute, or English and Italian swapped
How to fix
Set lang on the html element to the language the page is written in, for example lang="it" on an Italian page. On a multilingual site, give every language version its own value.

Link Previews and llms.txt

Tags that build the preview of a shared link, and the optional llms.txt file. The former AI Meta Tags check no longer runs: no search or AI engine documents those tags.

llms.txt Implementation

Unproven · not scored
What it checks
Looks for a plain-text /llms.txt (or /llm.txt) file at your domain root and rates how complete it looks. The check belongs to the AI-Specific dimension and is listed here because it is a file at your domain root.
Why it matters
llms.txt is an optional summary file. Google does not use it and no major AI engine is shown to, so a missing file is not a problem. The check is shown for information and does not count in your score.
How it is scored
Unproven, not scored. 25 points each for a title line (starting with #), a description and links, 15 for two or more # headings and 10 for more than 500 characters. Passes at 50; a missing file scores 0. Like every unproven check, it carries no weight either way.
Pass: 50 or more Fail: missing or below 50
How to fix
If you want one, publish a plain-text /llms.txt with a title, a short description and links to your key pages, following llmstxt.org. Skipping it costs you nothing in the score.
Example
# Example Company
> Leading provider of innovative solutions in the tech industry.

## Important pages
- [About](https://example.com/about): Company overview and mission
- [Products](https://example.com/products): Product catalog and specifications
- [Blog](https://example.com/blog): Technical articles and industry insights

## Contact
- Email: contact@example.com

OpenGraph Tags

Medium
What it checks
Checks the Open Graph tags that build the preview of a shared link: og:title, og:description, og:image and og:url (required), and og:type, og:site_name and og:locale (recommended). It also notes a relative og:image address, a missing og:image:width or og:image:height, and an og:url that differs from the page's address.
Why it matters
Social networks and chat apps use these tags to build the preview of a shared link: its title, text and image. Without them they guess, often badly.
How it is scored
Practitioner advice, counts at half weight. Up to 80 points for the four required tags (20 each, when present and not empty) and up to 20 for the three recommended ones, minus 5 for each problem noted. It passes when all four required tags are present and not empty.
Pass: og:title, og:description, og:image and og:url all filled in Fail: a required tag is missing or empty
How to fix
Add the four required tags to every page's head, plus og:type and og:site_name. Use an absolute https:// address for og:image and give its width and height.
Example
<head>
  <meta property="og:title" content="Your Page Title">
  <meta property="og:description" content="A short description of what the page offers">
  <meta property="og:image" content="https://example.com/image.jpg">
  <meta property="og:image:width" content="1200">
  <meta property="og:image:height" content="630">
  <meta property="og:url" content="https://example.com/page">
  <meta property="og:type" content="article">
  <meta property="og:site_name" content="Example">
</head>

Twitter Cards

Medium
What it checks
Checks the X (Twitter) card tags: twitter:card (required, with the type summary, summary_large_image, app or player), twitter:title and twitter:description (og:title and og:description count when they are missing), twitter:image (og:image counts) and twitter:site.
Why it matters
X (Twitter) uses these tags to build the preview of a shared link. Without them it falls back to Open Graph tags or shows a plain link.
How it is scored
Practitioner advice, counts at half weight. Starts at 100 and loses 40 without twitter:card, 25 for an unknown card type, 15 for each of title and description missing with no Open Graph tag to fall back on, and 5 for a missing image or twitter:site or a relative image address. It passes with a valid twitter:card plus a title and description, its own or from Open Graph.
Pass: a valid twitter:card with a title and description Fail: no twitter:card, an unknown card type, or no title or description
How to fix
Add twitter:card (summary_large_image suits most pages with an image) and, if you have no Open Graph tags, twitter:title, twitter:description and twitter:image. Add twitter:site with your X account.
Example
<head>
  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:title" content="Your Page Title">
  <meta name="twitter:description" content="A compelling description">
  <meta name="twitter:image" content="https://example.com/image.jpg">
</head>