Page title
titleThe title is the headline of every search result and the label on every browser tab. Google truncates it around 60 characters, so anything past that is written for nobody.
Web Scan runs 85 checks against the URL you give it. Each one is here with what it actually costs you to fail. No rule names without reasons.
titleThe title is the headline of every search result and the label on every browser tab. Google truncates it around 60 characters, so anything past that is written for nobody.
descriptionIt does not affect ranking, it affects clicks, it is the sales copy under your result. Without one, the engine picks a random sentence from your page, and it is rarely the one you would have chosen.
canonicalTracking parameters, trailing slashes and www variants create duplicate URLs for the same page. A canonical tells search engines which one counts. Web Scan also checks where yours points: a canonical aimed at a different URL tells search engines to index that page instead of this one, which is how pages get deindexed by accident.
viewportWithout a viewport tag, mobile browsers render at 980px wide and zoom out. The page is technically there but unreadable, and mobile usability failures suppress rankings on the majority of your traffic.
langA lang attribute tells search engines which language market you are in, and tells screen readers which voice and pronunciation rules to use. One attribute, two audiences, and without it English content can be read aloud with entirely wrong phonetics.
charsetDeclare utf-8 in the first bytes of the head or the browser guesses. When it guesses wrong you get mojibake in your own brand name, usually only on someone else’s machine.
h1One h1 states what the page is about, for both the accessibility tree and topical relevance. Zero leaves the page ambiguous; several blur what it is actually about.
hreflangOnly checked when the page declares language versions. Google ignores an hreflang set that is not internally consistent and says nothing about it: the wrong language ranks in the wrong country. Web Scan checks the codes against ISO 639-1 and 3166 (en-GB, not en-uk), that the page lists itself, that an x-default exists, and that the set is not undone by a canonical pointing elsewhere.
url-structurePeople read the URL in the search result before they click, and search engines read it as a small relevance hint. Uppercase letters, underscores, server file extensions and opaque numeric ids all make a URL harder to trust and to share. The query string is ignored, because what you typed may carry tracking parameters that are not the site's doing.
word-countWord count is not a ranking factor, but coverage is, and a page with a hundred words rarely covers anything. Counted on the crawlable text, the same text a crawler that does not run JavaScript receives.
readabilityFlesch reading ease and grade level, measured on paragraph prose only, because navigation labels are fragments that make any page look simple. Graded lightly and only at the extreme: Google does not rank by reading scores, but people do abandon prose they cannot get through, and assistants quote short self-contained sentences.
topic-focusWhen the title, the h1 and the opening paragraph name the page with different words, search engines have to infer the topic from the body. Web Scan takes the descriptive half of the title (not the brand) and looks for its words in the h1 and the first hundred words. Heuristic, and marked as such.
keyword-stuffingRepeating one term past a few percent of the text reads as stuffing to spam systems and as filler to people. Reported with the actual density so you can see what the page leans on.
internal-linksInternal links are how crawlers reach the rest of the site and how ranking signal flows through it. A page linking nowhere else on its own site is a dead end for both.
anchor-text"Read more" tells a search engine nothing about the page it points to, and a screen reader user browsing a list of links hears five identical entries. The link text should name the destination.
trust-pagesTrust is the part of E-E-A-T that quality raters weigh most, and it starts with the page saying who runs the site and how to reach them. Web Scan looks for about, contact and privacy links on the page itself, where a visitor would look.
authorOnly checked on pages that read as articles. An anonymous article is rated low on experience and expertise, and since the December 2025 core update that applies to competitive queries of every kind, not only health and finance. Bylines are read from meta tags, rel=author, author links and Article JSON-LD.
freshnessOnly checked on articles. Readers and assistants discount undated information, and an article last touched years ago is a candidate for a review. Dates come from article meta tags, JSON-LD and <time> elements.
structured-dataJSON-LD is what makes rich results eligible, star ratings, prices, FAQs, breadcrumbs. Invalid JSON is discarded silently, so a trailing comma costs you the feature without any error anywhere.
schema-validValid JSON is not enough: a Product without a name, a Review without a rating or an Organization still reading "[Company Name]" produces no rich result, and Search Console reports it only after the fact. Required properties are checked on top-level entities, so a nested publisher reference is not held to the rules of a full declaration.
schema-deprecatedHowTo, ClaimReview, SpecialAnnouncement, Dataset and several others no longer produce Google rich results. The markup is harmless but earns nothing. FAQPage is reported without a grade: it still works for government and health authorities, and other engines read it.
entityKnowledge panels and AI answers attribute content to entities, not URLs. An Organization or Person with sameAs links to Wikipedia, Wikidata, LinkedIn or GitHub is how an engine confirms you are the same entity everywhere, and brand presence on those platforms correlates with AI citations far more strongly than backlinks do.
statusOnly a 200 response is indexed and shared normally. If the page answers anything else, nothing else in the audit matters yet.
noindexA staging noindex that survives launch keeps the site out of search entirely, and nothing on the page looks wrong. It is the most expensive one-line mistake on the web and it usually takes weeks to notice.
robots-txtCrawlers request it before anything else. A leftover Disallow: / from staging blocks the whole site; no file at all means "crawl everything", which is rarely what you want once staging paths exist.
sitemapIt is how crawlers discover pages nothing links to yet, new posts, deep product pages, anything behind a search box. Reference it from robots.txt so it is found without being guessed.
redirectsEach hop costs a round trip before anything renders, and long chains leak ranking signal. http → https → www → final is three chances to lose a visitor on a slow connection.
rendered-contentA page whose text only appears after JavaScript runs is nearly empty in the HTML that gets sent. Google renders JS eventually, but link unfurlers, social previews and most other crawlers read what was sent, so the page they see has nothing in it.
soft-404A "not found" page that answers 200 is a soft 404. Search engines index the junk URLs that produce it, and your index fills with pages that say nothing.
meta-refreshOnly reported when present. A meta refresh redirect is slower than a server redirect, breaks the back button and passes ranking signal less reliably, and a timed self-refresh resets screen readers mid-sentence.
ai-search-botsOpenAI and Anthropic each run two crawlers: one gathers training material, a different one fetches a page in order to answer a question with it and cite you. Many robots.txt files predate the split and block both in the same group, which removes the site from those answers without touching its Google ranking, so nothing in analytics ever shows the loss.
ai-training-botsWhich training crawlers your robots.txt lets in, reported and deliberately not graded. Refusing to be trained on is a policy decision rather than a mistake. This is here so you can confirm the file says what you believe it says.
llms-txtA curated index pointing agents at clean Markdown instead of rendered HTML. Genuinely useful for developer documentation, because coding assistants fetch it live. Ungraded, because it is not an access control and the major assistants do not read it when answering a question: robots.txt is still the file that decides who can reach you.
answer-blocksFeatured snippets, People Also Ask and AI answers lift a block that answers one question on its own: a question heading followed by a 20-70 word direct answer, or a one-sentence definition. Heuristic, because it reads shape rather than quality.
content-structureA long page with no subheadings, lists or tables gives an assistant nothing to lift and a skimming reader nothing to land on. Checked on pages with 300 words or more.
citabilityHow many sections fall in the 100-200 word range that passage ranking and AI citation favour. Reported, not graded: it is a writing guide, not a defect.
claims-sourcedOnly checked when the page states at least three figures or findings. Assistants prefer pages that cite their own evidence, and statistics with no source read as invented.
image-dimensionsAn image without width and height reserves no space, so everything below it jumps when it loads. That jump is most of your Cumulative Layout Shift score and the reason people tap the wrong thing.
lcp-image-lazyThe first large image is usually the Largest Contentful Paint element. loading="lazy" on it makes the browser wait for layout before even requesting it, which is one of the most common and most expensive LCP mistakes.
img-alt-qualityMissing alt is an accessibility check; this one reads the alt text that is there. "image", "photo" or "IMG_0412.jpg" is announced to screen reader users and tells image search nothing.
image-formatsWebP is typically a quarter to a third smaller than JPEG at the same quality and AVIF smaller still. Images behind an image CDN or a framework loader that negotiates the format count as modern; icons are ignored.
responsive-imagesAn image declared 500px or wider with no srcset sends a phone the same file as a desktop. srcset and sizes let each device fetch what it can actually show.
lazy-loadingChecked on pages with six or more images. Images below the first screen should wait until they are needed, so they stop competing with the ones people can see.
httpsBrowsers label plain HTTP "Not secure" in the address bar, search engines demote it, and anything typed into the page is readable on the wire.
http-redirectOld links, typed addresses and printed URLs all arrive over http. Without a redirect they land on plaintext or an error instead of your site.
hstsA redirect still leaves the very first request downgradeable. Strict-Transport-Security tells the browser never to try http for your domain again, which is the part a redirect cannot fix.
cspThe main defence against an injected third-party script reading your forms. One compromised analytics tag on a checkout page is a card-skimming incident; a CSP is what makes that script fail to load.
nosniffWithout nosniff, a browser may decide an uploaded file is really a script and execute it. One header removes the entire class of problem.
framingIf your page can be framed, it can be layered invisibly over someone else’s buttons so clicks land on your app. frame-ancestors (or X-Frame-Options) is the fix.
referrer-policyBy default the full URL of the current page, including anything in the path, like a reset token or an account id, is sent to every third-party resource the page loads.
mixed-contentBrowsers block active content loaded over http from an https page. Those scripts and stylesheets do not degrade, they simply never run, and often only on the pages you did not test.
version-leakA Server or X-Powered-By header with a version number hands an attacker a shortlist of known CVEs to try. It gains you nothing and it is one line of config to strip.
csp-strengthHaving a Content-Security-Policy header and having a useful one are different things. A policy containing 'unsafe-inline' permits exactly the injected script a CSP exists to stop, and that is the shape a header copied from a blog post usually has.
cookie-flagsSecure keeps a session cookie off plain HTTP, HttpOnly keeps it out of reach of any script that gets injected into the page, and SameSite stops it riding along on cross-site requests. A session cookie missing HttpOnly turns any XSS into a full account takeover.
corsOnly checked when the response sends CORS headers at all. A wildcard origin combined with credentials is rejected by every browser, so the requests it was meant to allow are quietly failing, and Access-Control-Allow-Origin: null grants access to any sandboxed iframe on the web while looking restrictive.
permissions-policyPermissions-Policy switches off browser features the page does not use, camera, microphone, geolocation, so no embedded or injected script can ask for them.
exposed-keysEverything a page ships to a browser is public, including the API key someone put in a variable prefixed to make the build accept it. Web Scan reads the page and the scripts it links for AWS, Stripe, OpenAI, Anthropic, GitHub, Slack, SendGrid and mail credentials, database URLs with passwords, and private key blocks. Findings are redacted to the first and last characters, because the report itself is shareable.
public-api-keyGoogle browser keys for Maps and Firebase are meant to be public, so this is never a failure. It is worth seeing because unrestricted is the default: a key with no HTTP referrer restriction is a quota anyone can spend on your card.
supabase-keySupabase publishes two keys of identical shape. The anon key belongs in the browser; the service_role key bypasses every row-level security policy you wrote. They are told apart only by a claim inside the token, so the wrong one is easy to paste and impossible to notice, and it is a complete read and write of the database for anyone who opens devtools.
source-mapsA source map next to a bundle reconstitutes your original source: comments, dead branches, internal names, and any server-side helper that got bundled by accident. Useful in your error tracker, not on your CDN.
debug-outputA development bundle carries hot-reload plumbing and unminified source, and is several times the size of the build you meant to ship. Worse is a framework error page in production: those print file paths, versions and often the values that caused the error.
internal-hostslocalhost fallbacks and private-range addresses left in a bundle resolve to nothing for your visitors, and to something specific on your network for anyone reading it. It is a free map of staging hosts and internal APIs.
ttfbEverything else waits on the first byte. A slow document delays parsing, which delays every asset the parser has not discovered yet, the whole waterfall shifts right.
compressionText compresses four to eight times over with brotli or gzip, and enabling it is usually a single line of CDN config. Serving HTML uncompressed is free bandwidth thrown away.
html-sizeThe parser blocks on the document itself, so a megabyte of HTML, usually inlined state or a giant embedded payload, delays first paint no matter how fast your server is.
render-blockingA synchronous script in the head stops HTML parsing until it has downloaded and executed. Adding defer costs nothing and gives back that time on every single page load.
cache-headersWith no Cache-Control, CDNs and browsers guess, and they usually guess "revalidate every time", turning a cacheable page into a round trip for every visitor.
third-party-scriptsEvery third-party tag is a DNS lookup, a connection and main-thread work you do not control, and together they are the usual reason Interaction to Next Paint fails. Web Scan names the known ones so the list is easy to prune.
blocking-cssNothing paints until every stylesheet in <head> has arrived. A handful is normal; a long list means the first screen waits on CSS for pages nobody is looking at.
preconnectStylesheets and synchronous scripts from another origin need DNS, TCP and TLS before a byte arrives. A preconnect lets that handshake overlap with the HTML download instead of following it.
font-loadingWithout font-display, text stays invisible while web fonts download. A preloaded font without crossorigin is fetched twice. Both show up directly in Largest Contentful Paint.
img-altThe most common WCAG failure there is. Descriptive alt for meaningful images, alt="" for decorative ones, the empty attribute is a real answer, a missing one is not.
zoomuser-scalable=no fails WCAG 1.4.4 and makes the page unusable for anyone with low vision. It is almost always copied in from a template rather than chosen.
heading-orderScreen reader users navigate by jumping between headings. Skipping from h2 to h4 turns that outline into guesswork about what belongs to what.
form-labelsA placeholder is not a label. It vanishes as soon as someone types, so anyone who pauses mid-form loses the only clue about what the box wanted, and screen readers may never announce it. This is the second most common WCAG failure after missing alt text.
main-landmarkA <main> element lets screen reader users skip straight to the content, and it is how content extractors, including the ones feeding AI answers, tell the article from the navigation.
link-namesA link with no text, alt, title or aria-label is announced as "link" and nothing else. Marked as likely, because text drawn with CSS content does name a link and the served HTML cannot show it.
Social previews
8 checksOpen Graph title
og:titleThe headline in every unfurled link, Slack, LinkedIn, Discord, WhatsApp, iMessage. Missing it means platforms fall back to your page title, or to nothing.
Open Graph description
og:descriptionThe two lines under the headline in a shared link. It is the only body copy most people read before deciding whether to click.
Open Graph image
og:imageThe highest-leverage tag on the page. A link with a 1200×630 preview image gets several times the engagement of a bare URL. Crawlers fetch it without your cookies, so a URL behind auth or hotlink protection silently produces no preview at all.
Open Graph URL
og:urlThe canonical address platforms attribute the share to. Without it, the same page shared with different tracking parameters counts as different pages.
Open Graph type
og:typeTells platforms whether they are unfurling a website, an article, a product or a video, which decides how much of the card they render.
Open Graph site name
og:site_nameThe small label above the headline in a preview card. It is the difference between a link that looks like it comes from a brand and one that looks like it comes from a domain.
X / Twitter card
twitter:cardWithout summary_large_image, X renders a small square thumbnail instead of the full-width image card, the same asset at a fraction of the visual weight in the timeline.
Favicon
faviconIt appears in tabs, bookmarks, search results and link unfurls. Its absence is one of the few signals that reads instantly as "unfinished" to everyone, technical or not.