Skip to main content

The 18 Website Audit Checks We Run

Eighteen analyzers, grouped by the execution unit that runs them. For each one: what it checks, how it scores, and what to do about a low number.

A scan runs 18 analyzers in two phases. Seventeen of them run in the core phase, grouped into seven execution units that share their network work: one unit fetches your page once and four analyzers read that same response, another crawls up to 20 pages and five analyzers read that same crawl. That sharing is why a full audit finishes in seconds rather than minutes, and why a site that blocks one fetch loses a whole group at once rather than a single check.

The eighteenth analyzer, PageSpeed, calls Google's API and runs in a second phase on its own, so the core results reach you first. Every analyzer below is listed under the unit that runs it.

Page Analysis

Four analyzers share a single fetch of the URL you submitted. The page is requested once, with a 30-second budget, and every analyzer in this group reads that same response — so a site that answers once is not hit four times.

Page Analyzer

What it checks

  • Page title and meta description
  • Open Graph tags (og:title, og:description, og:image, og:type, og:url)
  • Twitter Card tags (twitter:card, twitter:title, twitter:description, twitter:image)
  • Favicon presence and URL resolution
  • Canonical URL and HTML lang attribute
  • Server headers: Server, X-Powered-By, Content-Type, Content-Encoding, Cache-Control
  • CDN detection from headers (Cloudflare, CloudFront, Fastly, Akamai)
  • Page load time, page size, and resource count estimate

Scoring

No score of its own. It supplies the fetched HTML and headers that the rest of this group, the CSS analyzer, and the GEO/AEO analyzer all read.

Network budget

30 seconds for the page fetch, shared with the whole group.

Tips to improve

  • Give every page a unique title and meta description
  • Add Open Graph and Twitter Card tags so shared links render properly
  • Set a canonical URL to avoid duplicate content issues
  • Include a lang attribute on the <html> element

Security Headers Analyzer

What it checks

  • Content-Security-Policy — must have default-src or script-src
  • Strict-Transport-Security — must have max-age greater than 0
  • X-Frame-Options — must be DENY or SAMEORIGIN
  • X-Content-Type-Options — must be nosniff
  • Referrer-Policy — must be non-empty
  • Permissions-Policy — must be non-empty

Scoring

The percentage of those 6 headers counted as present, rounded to a whole number. Five of six scores 83. An empty value counts as absent, for every header. Beyond that, only three are judged on what they contain: Content-Security-Policy, X-Frame-Options and X-Content-Type-Options are flagged weak in the results when they fail the criterion above, but a weak header still counts toward the score — a site sending all six scores 100 even if those three are weak. Strict-Transport-Security is the one header a bad value can sink: without a max-age above 0 it counts as missing outright. Referrer-Policy and Permissions-Policy have no weak state at all — any non-empty value passes. X-XSS-Protection is not on the list and is not scored: Chrome removed the XSS auditor it controlled in 2019, and OWASP's HTTP headers cheat sheet now says not to set the header, or to send X-XSS-Protection: 0, because the filter can create XSS vulnerabilities in otherwise safe sites. We do not charge points for a header nobody should send.

Network budget

None of its own — it reads the headers from the shared page fetch.

Tips to improve

  • Add a Content-Security-Policy header to limit where scripts can load from
  • Set Strict-Transport-Security with a max-age of at least 31536000 (one year)
  • Use X-Frame-Options DENY unless your site is meant to be embedded
  • Add Permissions-Policy to restrict access to camera, microphone, and geolocation

Technologies Analyzer

What it checks

  • CMS: WordPress, Shopify, Wix, Squarespace, Webflow, Drupal, Joomla
  • Frameworks: Next.js, React, Vue.js, Angular, Nuxt.js, Svelte, Gatsby, Remix
  • Analytics: Google Analytics, GTM, Facebook Pixel, Hotjar, Mixpanel, Segment, Plausible
  • CDN: Cloudflare, Fastly, Akamai, CloudFront, jsDelivr, unpkg
  • Libraries: jQuery, Bootstrap, Tailwind CSS, Font Awesome, Lodash
  • Hosting: Vercel, Netlify, GitHub Pages, Firebase, AWS
  • Servers: Nginx, Apache, PHP, Express.js (from response headers)

Scoring

Informational — no 0-100 score. Each detected technology is listed with a confidence level of high or medium.

Network budget

None of its own — it reads the shared page fetch.

Tips to improve

  • Review the detected list for outdated or unmaintained libraries
  • Confirm your analytics tools are actually loading in production

Mixed Content Analyzer

What it checks

  • HTTP resources referenced from an HTTPS page: images, scripts, stylesheets, iframes, video, and audio

Scoring

100 when the page is HTTPS with no mixed content. Otherwise 10 points per mixed resource, with an extra 5 points each for scripts and stylesheets, since those can rewrite the page.

Network budget

None of its own — it reads the shared page fetch.

Tips to improve

  • Serve every image, script, and stylesheet over HTTPS
  • Replace hardcoded http:// references with https://

AI Readiness (GEO/AEO)

One analyzer, and the reason this tool exists. It reads the HTML already fetched by Page Analysis, then makes its own 5-second requests for robots.txt, sitemap.xml and llms.txt to work out which AI crawlers you actually allow.

GEO/AEO Analyzer

What it checks

  • Structured data: JSON-LD presence, plus Organization, FAQPage, and HowTo schema
  • Social and discovery tags: Open Graph and Twitter Card
  • Content structure: a single H1, H2 count, and FAQ sections — an FAQ section means at least two entries in one FAQ shape: Question microdata, a group of details/summary accordions (any summary text counts, question mark or not), headings ending in a question mark, or question-shaped elements inside a container marked faq
  • Crawlability: sitemap, robots.txt, and access for 22 AI crawlers — search indexers (OAI-SearchBot, Claude-SearchBot, PerplexityBot, Applebot, Amzn-SearchBot, MistralAI-Index, DuckAssistBot), assistant fetchers (ChatGPT-User, Claude-User, Perplexity-User, Amzn-User, MistralAI-User, Meta-ExternalFetcher), and training crawlers (GPTBot, ClaudeBot, Google-Extended, Applebot-Extended, Meta-ExternalAgent, CCBot, Bytespider, Amazonbot, MistralAI-Training). Every crawler is placed in the category its operator documents. All 22 are reported; 6 of them move the score — OAI-SearchBot, PerplexityBot, Claude-SearchBot, ChatGPT-User, Claude-User and Perplexity-User. The rest are reported for context and cost nothing when blocked
  • llms.txt presence — reported as informational context only; no major AI search crawler fetches it today, though AI coding agents (Cursor, Claude Code, Copilot) commonly do and Google's Lighthouse now checks it in its Agentic Browsing category
  • Readability: Flesch reading ease and word count
  • Image alt tag completeness
  • Links: outbound and internal link counts. Links to .gov, .edu, and major news or platform domains are counted and shown, and score nothing
  • Answer-engine signals, reported as a checklist and never scored: FAQ and HowTo markup, question-and-answer heading patterns, the first paragraph, tables and lists, heading outline, and entity linking

Scoring

One score, on a 0-100 gauge, normalized from weighted components: structured data 25, crawlability 20, content structure 15, social tags 15, readability 15, alt text 5, links 5. The links 5 used to spend 2 of itself on an outbound .gov or .edu link; we dropped that in August 2026 because domain-suffix authority is link-equity folklore Google has denied even for classic SEO, and moved the 2 points to the two checks in that block that reason from mechanism — an outbound link cites a source, and internal links are how a crawler finds the rest of the site. The answer-engine signals are the other half of this analyzer and they carry no score at all. They used to: an 84-point ladder in which FAQ schema (20) and HowTo schema (15) were 42% of the total. We removed it in August 2026 because we could not defend those weights. Google dropped both schema types from rich results in 2023, nothing published ties either to being cited by an answer engine, and a page that is not an FAQ was losing points for not pretending to be one. The signals are still measured and still reported, one at a time, as present or absent.

Network budget

No fetch for the page itself; 5 seconds each for robots.txt, sitemap.xml and llms.txt.

Tips to improve

  • Add JSON-LD structured data, especially FAQPage and HowTo where the content genuinely is that shape
  • Use question-based headings followed by a short, direct answer
  • Blocking training crawlers (GPTBot, ClaudeBot, Google-Extended) is a content-policy choice — it does not cost you AI citations. Keep the search indexers (OAI-SearchBot, Claude-SearchBot, PerplexityBot) and assistant fetchers (ChatGPT-User, Claude-User) unblocked to stay visible in AI answers
  • Keep prose plain enough to quote. Our readability marker is a Flesch reading ease of 55-70, a house band rather than a published threshold

Accessibility

One analyzer, and it fetches the page itself rather than reading the shared response — WCAG checks need a DOM that has not been picked over by other analyzers first. It is not the only re-fetch in the core phase: the site crawler requests the submitted URL again as its crawl seed, and Redirect Check sends it a request of its own to trace the chain.

Accessibility Analyzer

What it checks

  • ARIA: landmarks, labels, descriptions, hidden elements, and invalid roles
  • Semantic HTML: <main>, <nav>, <header> and <footer> carry the semantic score, alongside heading structure. <article> and <aside> are detected and reported but earn nothing: neither is required by any WCAG criterion, and <article> carries no landmark role at all
  • Heading hierarchy: sequential h1-h6 ordering and a single h1
  • Form accessibility: labeled inputs, autocomplete, required fields
  • Image alt text: completeness and quality
  • Link accessibility: accessible text, generic-text warnings, skip links
  • Color contrast is reported as not analyzed. Measuring it needs rendered computed styles, which a static HTML pass cannot see, so no contrast ratio is ever produced and none feeds the score
  • Keyboard navigation: focus styles and tabindex issues
  • Multimedia: every <video> is checked for a captions or subtitles <track>, and one without either is a warning. Audio is not analyzed — an <audio> element raises a notice asking you to confirm a transcript exists, and no transcript check runs
  • Document structure: lang attribute, title, viewport meta
  • Tables: headers, scope, and captions
  • WCAG result: the report states which levels the detected errors sit at, or that none were detected at A or AA. It is never a conformance level. A static pass cannot see contrast, focus order or reflow, and conformance is a legal claim under the ADA and the EAA

Scoring

Starts at 100 and deducts: 10 per error and 3 per warning; 10 if the page has no ARIA landmarks at all; 15 if any invalid ARIA is found; 10 each for a missing lang attribute and a missing <title>; (100 − alt completeness) × 0.2 for image alt gaps; (100 − labeled input percentage) × 0.3 for form label gaps; 5 per empty link; 10 if there are no focus styles; and 3 per tabindex violation. It then applies (semantic score − 100) × 0.1, which costs up to 10 more unless the page carries the full set of semantic landmarks. The result is rounded, then clamped to 0-100. Two things to expect from that arithmetic: the per-issue and per-category deductions stack, so an image with no alt attribute costs 10 as an error and again through the alt-completeness term (an unlabeled input works the same way), and because each error is worth 10, a handful of them moves this score much further than a Lighthouse accessibility score would move.

Network budget

10 seconds for its own page fetch.

Tips to improve

  • Use semantic elements (<main>, <nav>, <header>) instead of bare <div>s
  • Give every meaningful image descriptive alt text
  • Pair every form input with a <label>
  • Keep one h1 per page and never skip a heading level
  • Leave visible focus styles in place for keyboard users

Site Crawler

Five analyzers share one crawl. Up to 20 pages are fetched, 5 seconds each, and all five analyzers read that same set — which is why they report on your site rather than on a single URL.

Robots.txt Analyzer

What it checks

  • robots.txt presence, and a parse of its User-agent groups, Disallow rules and directive syntax. Rules are matched as plain path prefixes: Allow lines and the * and $ wildcards are accepted as valid syntax but not applied, so a wildcard pattern is never treated as one (the RFC-style matcher runs in the GEO analyzer's AI-crawler check instead)
  • Disallow directives for the wildcard (*) user-agent
  • URLs that are disallowed but still linked from the site
  • Syntax errors in the file

Scoring

Starts at 100, or 80 if there is no robots.txt at all. Then 10 points per syntax error and 15 per URL that is disallowed but linked anyway.

Network budget

Part of the shared crawl: 5 seconds per request.

Tips to improve

  • Serve robots.txt from the site root
  • Check that no page you want indexed is caught by a Disallow prefix
  • Fix any syntax errors the analyzer flags

Sitemap Consistency Analyzer

What it checks

  • sitemap.xml or sitemap_index.xml presence
  • Sitemap index files: up to 10 same-origin child sitemaps are fetched and their URLs read (one level deep; children on another domain are not followed)
  • URLs in the sitemap compared against the URLs actually crawled, ignoring differences that do not change the page (a trailing slash, host capitalisation, the default port)
  • Broken URLs listed in the sitemap (up to 50 checked per audit)
  • Sitemap URLs your robots.txt tells our crawler not to fetch
  • Pages found by crawling but missing from the sitemap

Scoring

50 flat if no sitemap is found. Otherwise 100 minus 10 per broken sitemap URL, 5 per sitemap URL your robots.txt blocks our crawler from fetching, and 2 per crawled page missing from the sitemap. A sitemap URL that answers normally but our 20-page crawl did not walk to is listed for information only and costs nothing. If your sitemap index is larger than we read in one pass, the missing-from-sitemap check is suspended and deducts nothing — a page could be listed in a child sitemap we did not open, and we will not guess — and the report says how many children were read.

Network budget

Part of the shared crawl: 5 seconds per request.

Tips to improve

  • Publish a sitemap.xml covering every page you want indexed
  • Remove deleted and redirected URLs from it
  • Never list a page in your sitemap that robots.txt disallows
  • Keep index children on the same domain as the index itself
  • Submit the sitemap in Google Search Console

Canonical Tags Analyzer

What it checks

  • Exactly one canonical tag per page
  • Canonicals pointing at 404s or redirects
  • Canonicals pointing off-site
  • Multiple canonical tags on the same page

Scoring

100 minus 5 per missing canonical, 10 per page with multiple canonicals, 15 per canonical pointing at a 404, 10 per canonical pointing at a redirect, and 3 per off-site canonical.

Network budget

Part of the shared crawl: 5 seconds per request.

Tips to improve

  • Put a single canonical tag on every page
  • Make sure the canonical target returns 200, not a 301 or 404
  • Self-referencing canonicals are the safest default

Metadata Consistency Analyzer

What it checks

  • Title presence and length (ideal 20-70 characters)
  • Meta description presence and length (ideal 50-160 characters)
  • Duplicate titles across crawled pages
  • Open Graph tag presence (og:title, og:description, og:image, og:url)

Scoring

100 minus 15 per missing title, 10 per missing description, 5 per title-length problem, 3 per description-length problem, 8 per page carrying a duplicate title, and 2 per page missing any Open Graph tag — the Open Graph deduction is per page, so a page missing all four tags costs 2, not 8. Each deduction stops growing after four affected pages, ten for Open Graph, so no single problem can take the whole score down on its own; the categories still stack, so a site failing several ways at once can still reach 0. The duplicate deduction is per page, not per group: two pages sharing one title cost 16, three sharing one cost 24.

Network budget

Part of the shared crawl: 5 seconds per request.

Tips to improve

  • Keep titles between 20 and 70 characters, ideally 50-60
  • Keep descriptions between 50 and 160 characters
  • Never ship the same title on two pages
  • Add og:title, og:description, og:image, and og:url site-wide

Orphan Pages Analyzer

What it checks

  • Internal URLs that no crawled page links to, the homepage aside
  • Pages discovered by comparing the crawl against the sitemap

Scoring

100 minus the orphaned share of every internal URL the audit knows about: 100 − (orphans ÷ known internal URLs) × 100. The denominator is the discovered set, not the crawled set — the pages we fetched, the internal links they pointed at, and the sitemap entries — so it can be larger than the 20-page crawl.

Network budget

Part of the shared crawl: 5 seconds per request.

Tips to improve

  • Link important pages from your navigation, footer, or a hub page
  • Drop pages you deliberately keep unlinked from the sitemap too

CSS Analysis

One analyzer. It reads the stylesheets referenced by the page HTML that Page Analysis already fetched, then pulls each external file down on its own.

CSS Analyzer

What it checks

  • External stylesheets plus inline <style> blocks
  • Rule count, selector count, and average specificity
  • High-specificity selectors (above 300)
  • Duplicate selectors and !important usage
  • Media queries and breakpoints
  • Nesting depth, capped at 10 levels
  • Framework detection: Bootstrap, Tailwind, Foundation, Bulma, Material-UI
  • Design tokens: colors, fonts, spacing, border radius, breakpoints
  • Accessibility features: focus styles, reduced-motion support, dark mode

Scoring

Starts at 100. Each issue costs 10 (high severity), 5 (medium), or 2 (low). Then: 10 off for more than 100 !important declarations (5 off above 50), 10 off for more than 50 inline styles (5 off above 20), 5 off for more than 50 duplicate selectors, and 10 off for average specificity above 150 (5 off above 100). Focus styles, a reduced-motion query, and dark-mode support each add 5 back.

Network budget

10 seconds per external stylesheet.

Tips to improve

  • Cut !important usage — it makes every later override harder
  • Keep specificity low so components stay themeable
  • Add prefers-reduced-motion and dark mode media queries
  • Remove duplicate selectors to shrink the payload

Infrastructure

Two analyzers that never fetch your page. They talk to DNS and to the TLS socket directly, which is why they usually still return results when a WAF blocks everything else.

SSL Analyzer

What it checks

  • Certificate validity — is today inside validFrom and validTo
  • Days remaining until expiry
  • Hostname matching, exact and wildcard, per RFC 6125
  • Subject Alternative Names (SANs)
  • TLS protocol version
  • Certificate issuer and socket authorization status

Scoring

Binary: the certificate is valid or it is not. Days remaining is reported alongside it and highlighted as expiry approaches, but it does not feed a 0-100 score.

Network budget

15 seconds for the TLS handshake.

Tips to improve

  • Renew with at least 30 days of headroom
  • Cover every subdomain you serve in the certificate's SANs
  • Serve HTTPS — an HTTP-only site is reported as invalid

DNS Analyzer

What it checks

  • A records (IPv4) and AAAA records (IPv6)
  • MX records, with priority
  • TXT records, NS records, and CNAME records
  • The SOA record

Scoring

Informational — no 0-100 score. Records are listed as returned.

Network budget

Whatever the system DNS resolver allows.

Tips to improve

  • Add AAAA records so IPv6-only clients can reach you
  • Configure SPF, DKIM, and DMARC as TXT records for deliverability
  • Check MX records against what your email provider actually expects

PageSpeed

The eighteenth analyzer, and the only one that runs in its own phase. It calls Google's PageSpeed Insights API, which is slow enough that running it alongside the other 17 would hold up the whole audit — so the core results land first and this one arrives after.

PageSpeed Analyzer

What it checks

  • Lighthouse scores: Performance, Accessibility, Best Practices, SEO
  • Core Web Vitals: First Contentful Paint, Largest Contentful Paint, Total Blocking Time, Cumulative Layout Shift, Speed Index
  • The top 5 optimization opportunities
  • The top 5 diagnostics
  • A screenshot of the final rendered page

Scoring

Four 0-100 scores straight from Google Lighthouse. Their average is the audit's overall score, which is why the overall score is unavailable when this phase fails.

Network budget

90 seconds per attempt, with a countdown while it runs. A retryable failure is tried once more after a 15-second pause — about 195 seconds across both attempts — and if Google's API still has not answered, we make one last-resort measurement on our own infrastructure, capped at 60 seconds. The phase as a whole is bounded at 300 seconds.

Tips to improve

  • Improve Largest Contentful Paint by lazy-loading offscreen images
  • Cut Total Blocking Time by splitting large JavaScript bundles
  • Stop Cumulative Layout Shift by setting explicit dimensions on images and ads
  • Work the specific opportunities Lighthouse lists — they are ranked by impact

Next Steps