Website auditor scoring guide hero — futuristic twelve-dimension scoring algorithm visualization with radial spider chart, holographic percentage dials, and neon data streams
v5.2 — October 2026 · 100% Deterministic · Zero LLM Credits

Website Auditor
Scoring Guide

The complete reference for how our free website auditor evaluates your site across 12 dimensions with 540 field-level signals and checks. The headline is a field-signal count, not a count of independent or passing tests. Version 5.2 adds 19 passive coverage checks; review findings do not deduct points.

All scores computed from HTML source, HTTP headers, and robots.txt — no external APIs, no AI inference.

Unfamiliar with a metric below? Browse our glossary of 290+ terms

La edición actual, explicada · v5.2

Referencia actualizada: 9 de octubre de 2026. El total describe la capacidad del auditor, no las pruebas ejecutadas o aprobadas en una página.

471 campos + 50 comprobaciones de extensión + 19 comprobaciones de cobertura = 540

Piense en el catálogo como la caja de herramientas y en cada informe como una inspección concreta. Los campos incluyen observaciones, estimaciones y datos de contexto. Las comprobaciones interpretan esa evidencia. Un dato ausente no significa que se haya aprobado una prueba.

El catálogo se reconstruye desde el código en cada compilación. Un campo nuevo o un identificador de comprobación nuevo aumenta el total; reutilizar un campo no lo cuenta dos veces. Cambiar una recomendación no añade otra métrica. Un informe incompleto ya no puede reducir el total público.

Las nuevas comprobaciones de cobertura devuelven aprobado, fallo, revisión o no aplicable. Un fallo resta dos puntos en su dimensión; revisión y no aplicable no restan. Después se aplican los límites por sustancia del contenido y el promedio ponderado.

Un canonical diferente puede consolidar contenido equivalente. Noindex puede ser intencional. llms.txt es opcional; SearchAction no obtiene puntos adicionales. Las estimaciones de rendimiento no son mediciones de campo, y el análisis de HTML no certifica accesibilidad, seguridad ni indexación.

Descargar guía y catálogo completo de métricas (PDF en inglés)

How Scoring Works

Each dimension starts at 100 points. Points are deducted for missing elements, poor implementations, and security gaps. Thin or empty content then receives a substance-based cap, preventing missing content from earning an artificially strong result. The composite is the weighted average of the capped dimensions.

Futuristic SEO analytics dashboard visualization with holographic search metrics, ranking data streams, and interconnected keyword nodes
Futuristic SEO analytics dashboard visualization with holographic search metrics, ranking data streams, and interconnected keyword nodes
56 factors evaluated
Current source-derived deductions — 84 conditional rules

The factors below explain grouped concepts, so their deductions vary. These current base-engine rules give the exact conditional amounts. Extension outcomes and coverage checks are documented in the PDF; content-substance caps also apply.

Deduct 20 points

Missing title tag

When: NOT (p.titleLength >= 50 && p.titleLength <= 60) AND (p.titleLength === 0)

Deduct 5 points

Title tag is short ([observed value] chars)

When: NOT (p.titleLength >= 50 && p.titleLength <= 60) AND NOT (p.titleLength === 0) AND (p.titleLength < 50 && p.titleLength >= 30)

Deduct 10 points

Title tag is very short ([observed value] chars)

When: NOT (p.titleLength >= 50 && p.titleLength <= 60) AND NOT (p.titleLength === 0) AND NOT (p.titleLength < 50 && p.titleLength >= 30) AND (p.titleLength < 30)

Deduct 5 points

Title tag is too long ([observed value] chars — may be truncated in SERPs)

When: NOT (p.titleLength >= 50 && p.titleLength <= 60) AND NOT (p.titleLength === 0) AND NOT (p.titleLength < 50 && p.titleLength >= 30) AND NOT (p.titleLength < 30)

Deduct 8 points

Title tag contains a duplicated brand suffix (e.g., "My Page | Brand | Brand") — wastes title space and looks unprofessional in SERPs

When: (p.titleBrandSuffixDuplicated)

Deduct 4 points

Cloudflare Email Protection detected ([observed value] obfuscated links) — these appear as /cdn-cgi/l/email-protection and return 404 to crawlers

When: (p.cfEmailObfuscationDetected)

Deduct 6 points

[observed value] suspicious internal link pattern(s) detected: [observed value]

When: (p.internalBrokenLinkPatterns.length > 0)

Deduct 15 points

Missing meta description

When: NOT (p.metaDescLength >= 140 && p.metaDescLength <= 160) AND (p.metaDescLength === 0)

Deduct 3 points

Meta description is slightly short ([observed value] chars)

When: NOT (p.metaDescLength >= 140 && p.metaDescLength <= 160) AND NOT (p.metaDescLength === 0) AND (p.metaDescLength >= 120 && p.metaDescLength < 140)

Deduct 7 points

Meta description is short ([observed value] chars)

When: NOT (p.metaDescLength >= 140 && p.metaDescLength <= 160) AND NOT (p.metaDescLength === 0) AND NOT (p.metaDescLength >= 120 && p.metaDescLength < 140) AND (p.metaDescLength < 120)

Deduct 4 points

Meta description may be truncated ([observed value] chars)

When: NOT (p.metaDescLength >= 140 && p.metaDescLength <= 160) AND NOT (p.metaDescLength === 0) AND NOT (p.metaDescLength >= 120 && p.metaDescLength < 140) AND NOT (p.metaDescLength < 120)

Deduct 15 points

No H1 heading found

When: NOT (p.h1Count === 1) AND (p.h1Count === 0)

Deduct 8 points

Multiple H1 tags found ([observed value])

When: NOT (p.h1Count === 1) AND NOT (p.h1Count === 0)

Deduct 5 points

Heading hierarchy gaps: [observed value]

When: NOT (p.headingGaps.length === 0 && p.headingCount > 2) AND (p.headingGaps.length > 0)

Deduct 5 points

Very few headings for content length

When: (p.headingCount < 3 && p.wordCount > 300)

Deduct 8 points

Missing canonical URL

When: NOT (p.hasCanonical && p.canonicalMatchesUrl) AND (!p.hasCanonical)

Deduct 8 points

No Open Graph tags found

When: NOT (p.hasOpenGraph && p.ogMissing.length === 0) AND (!p.hasOpenGraph)

Deduct 4 points

Missing OG tags: [observed value]

When: NOT (p.hasOpenGraph && p.ogMissing.length === 0) AND NOT (!p.hasOpenGraph) AND (p.ogMissing.length > 0)

Deduct 5 points

No Twitter Card tags found

When: NOT (p.hasTwitterCard && p.twitterMissing.length === 0) AND (!p.hasTwitterCard)

Deduct 3 points

Missing Twitter tags: [observed value]

When: NOT (p.hasTwitterCard && p.twitterMissing.length === 0) AND NOT (!p.hasTwitterCard) AND (p.twitterMissing.length > 0)

Deduct 5 points

Missing lang attribute on <html>

When: NOT (p.hasLangAttr)

Deduct 3 points

Missing favicon

When: NOT (p.hasFavicon)

Deduct 4 points

[observed value] empty/unlabeled links found

When: (p.emptyLinks > 3)

Deduct 3 points

[observed value] broken anchor links detected

When: (p.brokenAnchors > 0)

Deduct 8 points

Thin content ([observed value] words)

When: NOT (p.wordCount >= 300 && p.wordCount <= 3000) AND (p.wordCount < 300)

Deduct 4 points

Deprecated HTML tags found: [observed value]

When: (p.deprecatedTags.length > 0)

Deduct 10 points

Page is set to noindex — search engines will not index this page

When: (p.hasRobotsMeta && p.robotsContent.includes('noindex'))

Deduct 5 points

Meta refresh redirect detected — harmful for SEO

When: (p.metaRefresh)

Deduct 8 points

Excessive links on page ([observed value]) — search engines may devalue link equity

When: (p.linkCount > 300)

Deduct 4 points

High link count ([observed value]) — above recommended range

When: NOT (p.linkCount > 300) AND (p.linkCount > 200)

Deduct 5 points

URL is very long ([observed value] chars) — may be truncated in SERPs and harder to share

When: (p.urlLength > 100)

Deduct 3 points

URL is longer than recommended ([observed value] chars)

When: NOT (p.urlLength > 100) AND (p.urlLength > 75)

Deduct 6 points

[observed value] external links missing rel="nofollow noopener noreferrer" — potential link equity leakage

When: (p.externalLinksWithoutRel > 10)

Deduct 3 points

[observed value] external links missing recommended rel attributes

When: NOT (p.externalLinksWithoutRel > 10) AND (p.externalLinksWithoutRel > 3)

Deduct 5 points

Hreflang tags found on a non-canonical page — search engines may ignore them

When: (p.hreflangOnNonCanonical)

Deduct 6 points

Long redirect chain ([observed value] hops) — slows crawling and dilutes PageRank

When: (p.redirectChainLength > 3)

Deduct 3 points

Redirect chain with [observed value] hops

When: NOT (p.redirectChainLength > 3) AND (p.redirectChainLength > 1)

Deduct 3 points

Title and description are identical to Open Graph tags — missed optimization opportunity

When: (p.duplicateTitleAndOg && p.duplicateDescAndOg)

Deduct 6 points

SPA framework detected ([observed value]) with thin initial HTML content — search engines may not index all content

When: (p.spaDetected && p.wordCount < 200)

Deduct 5 points

Low internal link ratio ([observed value]%) — most links point externally

When: (p.internalLinkRatio < 20 && p.linkCount > 10)

Deduct 4 points

Low anchor text diversity ([observed value]%) — many internal links use identical text

When: (p.anchorTextDiversity < 30 && p.internalLinks > 10)

Deduct 6 points

Multiple canonical tags found — search engines may ignore all of them

When: (p.multipleCanonicals)

Deduct 3 points

Title and H1 share no keywords — misaligned topic signals

When: NOT (p.titleH1Overlap > 0.5 && p.titleH1Overlap < 1) AND (p.titleH1Overlap === 0 && p.h1Count > 0 && p.titleLength > 0)

Deduct 5 points

All [observed value] external links are nofollow — no outbound link authority signals

When: (p.externalLinks > 0) AND NOT (p.dofollowExternalLinks >= 2 && p.dofollowExternalLinks <= 5) AND (p.dofollowExternalLinks === 0 && p.externalLinks > 3)

Deduct 2 points

Only 1 dofollow external link — consider adding a few more to authoritative sources

When: (p.externalLinks > 0) AND NOT (p.dofollowExternalLinks >= 2 && p.dofollowExternalLinks <= 5) AND NOT (p.dofollowExternalLinks === 0 && p.externalLinks > 3) AND (p.dofollowExternalLinks === 1)

Deduct 5 points

High dofollow external link count ([observed value]) — excessive link equity leakage

When: (p.externalLinks > 0) AND NOT (p.dofollowExternalLinks >= 2 && p.dofollowExternalLinks <= 5) AND NOT (p.dofollowExternalLinks === 0 && p.externalLinks > 3) AND NOT (p.dofollowExternalLinks === 1) AND (p.dofollowExternalLinks > 10)

Deduct 2 points

[observed value] dofollow external links — slightly above optimal range

When: (p.externalLinks > 0) AND NOT (p.dofollowExternalLinks >= 2 && p.dofollowExternalLinks <= 5) AND NOT (p.dofollowExternalLinks === 0 && p.externalLinks > 3) AND NOT (p.dofollowExternalLinks === 1) AND NOT (p.dofollowExternalLinks > 10) AND (p.dofollowExternalLinks > 5)

Deduct 4 points

Primary keyword "[observed value]" not found in H1

When: (p.primaryKeyword && p.h1Count > 0) AND NOT (p.h1ContainsKeyword)

Deduct 3 points

Primary keyword missing from first paragraph

When: (p.primaryKeyword && p.wordCount > 100) AND NOT (p.firstParaContainsKeyword)

Deduct 5 points

Weak E-E-A-T signals ([observed value] indicators)

When: NOT (p.eatSignalCount >= 5) AND NOT (p.eatSignalCount >= 3)

Deduct 2 points

Conditional deduction; see the exact trigger.

When: (!p.hasAboutPage)

Deduct 2 points

Conditional deduction; see the exact trigger.

When: (!p.hasContactPage)

Deduct 2 points

Moderate readability ([observed value] Flesch) — content may be difficult for some readers

When: (p.fleschReadingEase > 0 && p.wordCount > 100) AND NOT (p.fleschReadingEase >= 60) AND (p.fleschReadingEase >= 40)

Deduct 4 points

Low readability score ([observed value] Flesch) — content is hard to read

When: (p.fleschReadingEase > 0 && p.wordCount > 100) AND NOT (p.fleschReadingEase >= 60) AND NOT (p.fleschReadingEase >= 40)

Deduct 2 points

Missing og:locale tag — social platforms may guess language/region

When: (p.hasOpenGraph) AND (!p.ogHasLocale)

Deduct 1 points

Conditional deduction; see the exact trigger.

When: (p.hasOpenGraph) AND (p.ogImageUrl) AND NOT (p.ogImageIsWebp)

Deduct 1 points

Conditional deduction; see the exact trigger.

When: (p.hasOpenGraph) AND (p.ogImageUrl) AND NOT (p.ogImageDimensionHint === 'optimal') AND (p.ogImageDimensionHint === 'acceptable')

Deduct 3 points

OG image dimensions too small for social platforms

When: (p.hasOpenGraph) AND (p.ogImageUrl) AND NOT (p.ogImageDimensionHint === 'optimal') AND NOT (p.ogImageDimensionHint === 'acceptable') AND (p.ogImageDimensionHint === 'too_small')

Deduct 1 points

Conditional deduction; see the exact trigger.

When: (p.hasOpenGraph) AND (p.hasArticleSchema || p.wordCount > 500) AND NOT (p.articlePublishedTime)

Deduct 1 points

Conditional deduction; see the exact trigger.

When: (p.hasOpenGraph) AND (p.hasArticleSchema || p.wordCount > 500) AND NOT (p.articleModifiedTime)

Deduct 1 points

Conditional deduction; see the exact trigger.

When: (p.hasTwitterCard) AND NOT (p.twitterCardType === 'summary_large_image') AND (p.twitterCardType === 'summary')

Deduct 2 points

Twitter card type not specified

When: (p.hasTwitterCard) AND NOT (p.twitterCardType === 'summary_large_image') AND NOT (p.twitterCardType === 'summary') AND (!p.twitterCardType)

Deduct 3 points

Low internal link density ([observed value]/1k words) — below optimal 2–5 range

When: (p.wordCount >= 300) AND NOT (density >= 2 && density <= 5) AND (density < 2 && density > 0)

Deduct 5 points

No internal links in content body

When: (p.wordCount >= 300) AND NOT (density >= 2 && density <= 5) AND NOT (density < 2 && density > 0) AND (density === 0)

Deduct 3 points

Very high internal link density ([observed value]/1k words) — may appear spammy

When: (p.wordCount >= 300) AND NOT (density >= 2 && density <= 5) AND NOT (density < 2 && density > 0) AND NOT (density === 0) AND (density > 50)

Deduct 8 points

Keyword stuffing detected: "[observed value]" appears [observed value] times ([observed value]% density — exceeds 3%)

When: (p.primaryKeyword && p.wordCount >= 100) AND (p.isKeywordStuffed)

Deduct 2 points

Low keyword density ([observed value]%) for "[observed value]"

When: (p.primaryKeyword && p.wordCount >= 100) AND NOT (p.isKeywordStuffed) AND NOT (p.keywordDensityPercent >= 0.5 && p.keywordDensityPercent <= 2.5) AND (p.keywordDensityPercent > 0 && p.keywordDensityPercent < 0.5)

Deduct 3 points

Primary keyword "[observed value]" not found in body content

When: (p.primaryKeyword && p.wordCount >= 100) AND NOT (p.isKeywordStuffed) AND NOT (p.keywordDensityPercent >= 0.5 && p.keywordDensityPercent <= 2.5) AND NOT (p.keywordDensityPercent > 0 && p.keywordDensityPercent < 0.5) AND (p.keywordOccurrences === 0)

Deduct 2 points

Moderate passive voice ([observed value]%)

When: (p.wordCount >= 200 && p.passiveVoiceRatio > 0) AND NOT (p.passiveVoiceRatio <= 15) AND (p.passiveVoiceRatio <= 30)

Deduct 4 points

High passive voice ratio ([observed value]%) — harder for AI/voice extraction

When: (p.wordCount >= 200 && p.passiveVoiceRatio > 0) AND NOT (p.passiveVoiceRatio <= 15) AND NOT (p.passiveVoiceRatio <= 30)

Deduct 3 points

Long content without Table of Contents

When: NOT (p.hasTableOfContents && p.wordCount >= 800) AND (!p.hasTableOfContents && p.wordCount >= 1500)

Deduct 2 points

Conditional deduction; see the exact trigger.

When: NOT (p.zeroClickOptimized) AND (p.wordCount >= 500)

Deduct 2 points

Conditional deduction; see the exact trigger.

When: NOT (p.entitySalienceScore >= 50) AND NOT (p.entitySalienceScore >= 20) AND (p.wordCount >= 500)

Deduct 2 points

Conditional deduction; see the exact trigger.

When: NOT (p.bingeworthySignals >= 3) AND (p.bingeworthySignals === 0 && p.wordCount >= 500)

Deduct 3 points

No social sharing buttons/widgets detected

When: NOT (p.hasSocialShareButtons)

Deduct 1 points

Conditional deduction; see the exact trigger.

When: NOT (p.ogSharingCompleteness >= 100) AND (p.ogSharingCompleteness >= 67)

Deduct 3 points

Low OG sharing completeness ([observed value]%) — social previews will be poor

When: NOT (p.ogSharingCompleteness >= 100) AND NOT (p.ogSharingCompleteness >= 67) AND (p.ogSharingCompleteness < 67)

Deduct 6 points

Multiple <title> tags detected ([observed value]) — search engines may use an unintended title

When: (p.multipleTitleTags)

Deduct 6 points

Multiple meta descriptions detected ([observed value]) — engines may ignore them or pick the wrong one

When: (p.multipleMetaDescriptions)

Deduct 3 points

[observed value] internal link(s) use rel="nofollow" — this wastes internal link equity

When: (p.nofollowInternalLinks > 0)

Deduct 4 points

Conflicting character-encoding declarations detected — can cause garbled text and indexing issues

When: (p.conflictingCharacterEncoding)

Deduct 8 points

Legacy frames/framesets detected ([observed value]) — content inside frames is poorly indexed

When: (p.hasFrames)

Deduct 5 points

[observed value] image(s) have a missing or empty src — broken images hurt UX and image search

When: (p.brokenImages > 0)

Deduct 2 points

Inline CSS validation hints: [observed value]

When: (p.cssValidationHints.length > 0)

Varies

Title Tag Presence & Length

The <title> element is the single most important on-page SEO signal. Google displays it in SERPs and uses it for ranking. Optimal length is 50–60 characters (Google 2025–2026 recommendation); shorter titles waste ranking potential, longer titles get truncated.

Varies

Meta Description Presence & Length

Meta descriptions generate the snippet text in SERPs. A missing or poorly-sized description (optimal: 120–160 chars) leads Google to auto-generate snippets, often yielding lower click-through rates.

Varies

Meta Keywords Tag

The legacy engine records this field and applies a small internal rubric deduction when missing. Google does not use meta keywords for web search ranking; this internal score is not a Google ranking rule.

Varies

H1 Heading (Count & Content)

Exactly one H1 per page is best practice. Multiple H1s dilute topical focus; a missing H1 removes the primary heading signal. We also check whether the H1 contains your primary keyword (h1ContainsKeyword).

Varies

Heading Hierarchy (H2–H6)

We parse the full heading hierarchy (h2Count, h3Count, headingCount) and detect heading gaps — skipping from H2 to H4, for example, breaks semantic structure and confuses crawlers.

Varies

Canonical Tag & Consistency

Missing or multiple canonical annotations are scored. A different canonical URL can intentionally consolidate equivalent content and receives no mismatch penalty. Distinct pagination normally needs its own canonical.

Varies

Open Graph Tags (Completeness)

We audit all OG tags: og:title, og:description, og:image, og:type, og:url, og:locale. Each missing tag (ogMissing) reduces social sharing effectiveness. We also check ogHasLocale, ogImageIsWebp, ogImageDimensionHint, and whether og duplicates the title/description (duplicateTitleAndOg, duplicateDescAndOg).

Varies

Twitter Card Tags

Separate from OG, Twitter cards require twitter:card, twitter:title, twitter:description, twitter:image. We verify twitterCardType (summary_large_image is optimal) and flag twitterMissing tags.

Varies

Social Sharing Completeness

We calculate ogSharingCompleteness (0–100) combining OG + Twitter Card coverage. We also detect social share widgets (hasSocialShareButtons, socialShareWidgets) that amplify content distribution.

Varies

Image Alt Text Coverage

Every image needs descriptive alt text. We count imagesWithoutAlt and imagesWithEmptyAlt separately — empty alt="" is valid only for decorative images. Missing alt text loses both SEO image ranking and accessibility.

Varies

Internal Link Architecture

We measure internalLinks, internalLinkRatio, internalLinkDensityPer1k (links per 1,000 words), and anchorTextDiversity. A ratio below 0.5 or density below 2 per 1k words signals poor internal linking.

Varies

External Link Quality

We count externalLinks, externalLinksWithoutRel (missing noopener/noreferrer), and analyze the dofollowExternalLinks vs. nofollowExternalLinks ratio (externalLinkDofollowRatio). Excessive dofollow outbound links dilute PageRank.

Varies

Broken & Empty Links

brokenAnchors (href="#" or empty href) and emptyLinks waste crawl budget and create dead-end user experiences. We also detect internalBrokenLinkPatterns for systematic link rot.

Varies

URL Length & Structure

URLs over 75 characters are harder to share and may be truncated in SERPs. We measure urlLength and check keywordInUrl for topical relevance.

Varies

Keyword Targeting & Density

We identify the primaryKeyword, measure keywordDensityPercent, keywordOccurrences, and detect isKeywordStuffed (>3% density). We also verify h1ContainsKeyword and firstParaContainsKeyword for topical reinforcement.

Varies

Content Depth & Word Count

wordCount, paragraphCount, and avgWordsPerParagraph measure content substance. Pages under 300 words are flagged as thinContentSignal. We also check titleH1Overlap — high overlap suggests lazy optimization.

Varies

Readability & Writing Quality

fleschReadingEase measures text complexity (60–70 is ideal for web). passiveVoiceRatio above 20% reduces engagement. contentReadabilityHints provide specific improvement suggestions.

Varies

E-E-A-T Signals

We count eatSignalCount across: hasAboutPage, hasContactPage, hasTestimonialsPage, hasAuthorBox, hasTrustBadges, hasAuthorInfo, and hasExpertiseSignals. E-E-A-T (Experience, Expertise, Authoritativeness, Trustworthiness) is Google's quality rater framework.

Varies

Robots Meta & Directives

hasRobotsMeta and robotsContent describe indexing instructions. A canonical does not override noindex. Intentional exclusions are reviewed rather than automatically penalized; where directives conflict, the more restrictive instruction applies.

Varies

Favicon & Touch Icons

hasFavicon and hasAppleTouchIcon affect brand recognition in browser tabs, bookmarks, and mobile home screens. Missing favicons look unprofessional in SERPs.

Varies

Doctype & Charset

A valid doctype declaration and hasCharset (UTF-8) ensure proper rendering across all browsers and correct character encoding for international content.

Varies

Deprecated HTML Tags

deprecatedTags like <font>, <center>, <marquee> signal unmaintained code and may cause rendering inconsistencies across modern browsers.

Varies

Meta Refresh Redirect

metaRefresh redirects are discouraged by Google — they prevent proper HTTP status code handling, confuse crawlers, and degrade user experience.

Varies

Redirect Chain Length

Each hop in a redirectChainLength wastes crawl budget and adds latency. More than 2 redirects signals poor URL management.

Varies

Title–Brand Suffix Duplication

titleBrandSuffixDuplicated detects "| Brand | Brand" patterns where the brand name appears twice in the title, wasting valuable character space.

Varies

Cloudflare Email Obfuscation

cfEmailObfuscationDetected with high cfEmailObfuscationCount can interfere with crawlers parsing contact information and may affect E-E-A-T signals.

Varies

Zero-Click Optimization

zeroClickOptimized checks for TL;DR blocks (tldrBlockCount), definition lead paragraphs (definitionLeadParagraphs), and hasTableOfContents — content patterns that win featured snippets and AI Overviews.

Varies

Entity Salience & Mentions

entitySalienceScore measures how prominently key entities appear. relatedEntityMentions and entityMentions help search engines build topical authority graphs.

Varies

Bingeworthy Content Signals

bingeworthySignals detect internal content loops, "related posts" sections, and series navigation that increase session duration and pages per visit.

Varies

Enhanced OG Image & Article Dates

ogImageUrl quality, articlePublishedTime, and articleModifiedTime provide temporal signals for content freshness in social shares and news carousels.

Varies

Hreflang on Non-Canonical Pages

hreflangOnNonCanonical is a critical error: serving hreflang tags on non-canonical URLs creates conflicting language signals that can cause wrong-language pages in SERPs.

Varies

BreadcrumbList Schema Coverage · v5.0

When breadcrumb navigation is present in the UI but no BreadcrumbList JSON-LD is found, Google cannot render breadcrumb rich results. We detect breadcrumb UI (nav[aria-label="breadcrumb"], ol[itemtype*="BreadcrumbList"]) and cross-check for matching structured data.

Varies

E-E-A-T Authorship Linkage · v5.0

We check for verifiable authorship markup — rel="author", itemprop="author", and sameAs identity links. Author linkage strengthens Google's Experience/Expertise signals; its absence weakens the trust half of E-E-A-T.

Varies

IndexNow Protocol Adoption · v5.0

We look for an IndexNow signal (an indexnow reference or the {key}.txt verification file in robots.txt). Adopting IndexNow (Bing/Yandex/Seznam) pushes instant crawl notifications when content changes, accelerating discovery of new and updated pages.

Varies

Multiple Title Tags · v5.1

Whether the multiple title tags signal was detected. Multiple <title> tags detected ([observed value]) — search engines may use an unintended title

Varies

Title Tag Count · v5.1

Number of title elements in the HTML. This is the measured count underlying the multiple-title warning.

Varies

Multiple Meta Descriptions · v5.1

Whether the multiple meta descriptions signal was detected. Multiple meta descriptions detected ([observed value]) — engines may ignore them or pick the wrong one

Varies

Meta Description Count · v5.1

Number of meta description elements. More than one can create ambiguous snippet instructions.

Varies

Meta Keywords Length · v5.1

Character length of the meta keywords value. This is descriptive metadata; Google does not use the meta keywords tag for web search ranking.

Varies

Hreflang Element Count · v5.1

The recorded hreflang element count value. [observed value] hreflang annotation(s) present for international targeting

Varies

Meta Refresh Url · v5.1

Destination declared by a meta refresh instruction, when present. Inspect the destination and prefer an appropriate server redirect where possible.

Varies

Nofollow Internal Links · v5.1

Numeric value for nofollow internal links. [observed value] internal link(s) use rel="nofollow" — this wastes internal link equity

Varies

Charset Type · v5.1

The recorded charset type value. Character encoding declared as [observed value]

Varies

Content Type Header · v5.1

The HTTP Content-Type response value, including its declared character encoding when supplied.

Varies

Conflicting Character Encoding · v5.1

Whether the conflicting character encoding signal was detected. Conflicting character-encoding declarations detected — can cause garbled text and indexing issues

Varies

Has Frames · v5.1

Whether the frames signal was detected. Legacy frames/framesets detected ([observed value]) — content inside frames is poorly indexed

Varies

Frameset Count · v5.1

Number of legacy frameset elements detected; these are separate from modern iframe embeds.

Varies

Css Validation Hints · v5.1

The observed list of css validation hints. Inline CSS validation hints: [observed value]

Varies

Broken Images · v5.1

Numeric value for broken images. [observed value] image(s) have a missing or empty src — broken images hurt UX and image search

−2 / 0

Canonical absolute · v5.2

Canonical must be an absolute HTTP(S) URL. A failure deducts two points; pass, review and not applicable deduct none.

−2 / 0

Canonical fragment · v5.2

Canonical must not identify a fragment. A failure deducts two points; pass, review and not applicable deduct none.

−2 / 0

Canonical head · v5.2

Canonical annotations belong in the document head. A failure deducts two points; pass, review and not applicable deduct none.

−2 / 0

Pagination canonical · v5.2

Distinct paginated content needs its own canonical; review whether this URL is a duplicate filter. A failure deducts two points; pass, review and not applicable deduct none.

−2 / 0

Pagination noindex · v5.2

Review noindex on genuine pagination; preserve exclusions for filtered duplicates. A failure deducts two points; pass, review and not applicable deduct none.

−2 / 0

Header meta index conflict · v5.2

Conflicting index directives: the more restrictive directive applies. A failure deducts two points; pass, review and not applicable deduct none.

−2 / 0

Url template links · v5.2

Search templates belong in metadata, not literal crawlable links. A failure deducts two points; pass, review and not applicable deduct none.

Futuristic website performance metrics dashboard with glowing speedometer gauges, Core Web Vitals indicators, and data flow optimization panels
Futuristic website performance metrics dashboard with glowing speedometer gauges, Core Web Vitals indicators, and data flow optimization panels
33 factors evaluated
Current source-derived deductions — 56 conditional rules

The factors below explain grouped concepts, so their deductions vary. These current base-engine rules give the exact conditional amounts. Extension outcomes and coverage checks are documented in the PDF; content-substance caps also apply.

Deduct 5 points

Conditional deduction; see the exact trigger.

When: NOT (s.responseTimeMs < 500) AND (s.responseTimeMs < 1000)

Deduct 12 points

Slow server response: [observed value]ms

When: NOT (s.responseTimeMs < 500) AND NOT (s.responseTimeMs < 1000) AND (s.responseTimeMs < 2000)

Deduct 20 points

Very slow server response: [observed value]ms

When: NOT (s.responseTimeMs < 500) AND NOT (s.responseTimeMs < 1000) AND NOT (s.responseTimeMs < 2000)

Deduct 5 points

Large HTML document: [observed value]KB

When: NOT (p.htmlSizeKb < 100) AND NOT (p.htmlSizeKb < 300) AND (p.htmlSizeKb < 500)

Deduct 15 points

Very large HTML: [observed value]KB

When: NOT (p.htmlSizeKb < 100) AND NOT (p.htmlSizeKb < 300) AND NOT (p.htmlSizeKb < 500) AND NOT (isModernFramework && p.htmlSizeKb < 1500)

Deduct 5 points

[observed value] render-blocking script(s)

When: NOT (p.renderBlockingScripts === 0) AND NOT (p.renderBlockingScripts <= 3 && isModernFramework) AND (p.renderBlockingScripts <= 2)

Deduct 12 points

[observed value] render-blocking scripts slow down initial paint

When: NOT (p.renderBlockingScripts === 0) AND NOT (p.renderBlockingScripts <= 3 && isModernFramework) AND NOT (p.renderBlockingScripts <= 2)

Deduct 8 points

No lazy loading on images

When: NOT (p.imageCount > 0 && p.hasLazyImages) AND (p.imageCount > 5 && !p.hasLazyImages)

Deduct 6 points

No WebP or AVIF image formats found

When: NOT (p.hasWebpAvif) AND (p.imageCount > 0)

Deduct 5 points

No responsive image srcset found

When: NOT (p.hasSrcset) AND (p.imageCount > 3)

Deduct 5 points

Only [observed value]/[observed value] images have width/height attributes

When: NOT (p.imageCount > 0 && p.imagesWithWidthHeight >= p.imageCount * 0.8) AND (p.imageCount > 3 && p.imagesWithWidthHeight < p.imageCount * 0.5)

Deduct 3 points

Conditional deduction; see the exact trigger.

When: NOT (p.hasPreconnect)

Deduct 3 points

Conditional deduction; see the exact trigger.

When: NOT (p.hasPreload)

Deduct 3 points

No font-display property found

When: NOT (p.hasFontDisplay)

Deduct 5 points

No effective Cache-Control header

When: NOT (cc && (cc.includes('max-age') || cc.includes('s-maxage')))

Deduct 3 points

[observed value] inline <style> blocks

When: (p.inlineStyles > 5)

Deduct 3 points

[observed value] inline scripts

When: (p.inlineScripts > 10 && !isModernFramework)

Deduct 8 points

Large CSS payload (~[observed value]KB across [observed value] files) — slows rendering

When: (p.totalCssKb > 500)

Deduct 3 points

Moderate CSS payload (~[observed value]KB)

When: NOT (p.totalCssKb > 500) AND (p.totalCssKb > 200)

Deduct 10 points

Heavy JavaScript payload (~[observed value]KB across [observed value] files)

When: (p.totalJsKb > 1000 && !isModernFramework)

Deduct 5 points

Moderate JavaScript payload (~[observed value]KB)

When: NOT (p.totalJsKb > 1000 && !isModernFramework) AND (p.totalJsKb > 500 && !isModernFramework)

Deduct 5 points

Large JS bundle (~[observed value]KB) even for framework app

When: NOT (p.totalJsKb > 1000 && !isModernFramework) AND NOT (p.totalJsKb > 500 && !isModernFramework) AND (p.totalJsKb > 2000 && isModernFramework)

Deduct 4 points

Redirect chain ([observed value] hops) adds latency to page load

When: (p.redirectChainLength > 2)

Deduct 4 points

[observed value] links increase DOM size and parsing time

When: (p.linkCount > 200)

Deduct 4 points

HTTP/1.1 detected — no multiplexing

When: NOT (p.httpVersion === 'HTTP/3') AND NOT (p.httpVersion === 'HTTP/2') AND (!isModernFramework)

Deduct 5 points

No CDN detected

When: NOT (p.cdnDetected)

Deduct 6 points

No response compression detected

When: NOT (p.compressionType === 'br') AND NOT (p.compressionType === 'gzip') AND (p.compressionType === 'none')

Deduct 6 points

[observed value] third-party scripts from [observed value] domains — significant performance impact

When: (p.thirdPartyScriptCount > 10)

Deduct 3 points

[observed value] third-party scripts detected

When: NOT (p.thirdPartyScriptCount > 10) AND (p.thirdPartyScriptCount > 5)

Deduct 4 points

No resource hints found

When: NOT (p.totalResourceHints >= 5) AND (p.totalResourceHints === 0)

Deduct 4 points

[observed value] font files loaded — excessive font weight

When: (p.fontFileCount > 4)

Deduct 2 points

Conditional deduction; see the exact trigger.

When: NOT (p.preloadFontCount > 0) AND (p.fontFileCount > 0)

Deduct 5 points

[observed value] render-blocking CSS files — delays first paint

When: (p.renderBlockingCssCount > 3)

Deduct 2 points

[observed value] render-blocking CSS file(s)

When: NOT (p.renderBlockingCssCount > 3) AND (p.renderBlockingCssCount > 1 && !isModernFramework)

Deduct 4 points

Estimated CSS bundle ~[observed value]KB — above optimal

When: (p.totalCssBundleKb > 300)

Deduct 5 points

Estimated JS bundle ~[observed value]KB — heavy payload

When: (p.totalJsBundleKb > 1500 && !isModernFramework)

Deduct 3 points

Large JS bundle (~[observed value]KB) even for framework app

When: NOT (p.totalJsBundleKb > 1500 && !isModernFramework) AND (p.totalJsBundleKb > 3000 && isModernFramework)

Deduct 2 points

Potentially unused CSS detected (large stylesheet count relative to page complexity)

When: (p.unusedCssHint)

Deduct Math.min(p.longTaskScriptHints.length * 2, 6) points

Potential long-task scripts: [observed value]

When: (p.longTaskScriptHints.length > 0 && !isModernFramework)

Deduct 5 points

Estimated LCP: ~[observed value]ms — needs improvement (goal: <2.5s)

When: (p.lcpEstimateMs > 0) AND NOT (p.lcpEstimateMs <= 2500) AND (p.lcpEstimateMs <= 4000)

Deduct 10 points

Poor estimated LCP: ~[observed value]ms — exceeds 4s threshold

When: (p.lcpEstimateMs > 0) AND NOT (p.lcpEstimateMs <= 2500) AND NOT (p.lcpEstimateMs <= 4000)

Deduct 8 points

High estimated CLS: [observed value] — exceeds Google's 0.25 threshold

When: (p.clsEstimate > 0.25)

Deduct 4 points

Moderate estimated CLS: [observed value] — above 0.1 "good" threshold

When: NOT (p.clsEstimate > 0.25) AND (p.clsEstimate > 0.1)

Deduct 4 points

Estimated INP: ~[observed value]ms — needs improvement (goal: <200ms)

When: (p.inpEstimateMs > 0) AND NOT (p.inpEstimateMs <= 200) AND (p.inpEstimateMs <= 500 && !isModernFramework)

Deduct 2 points

Estimated INP: ~[observed value]ms — slightly above threshold for framework app

When: (p.inpEstimateMs > 0) AND NOT (p.inpEstimateMs <= 200) AND NOT (p.inpEstimateMs <= 500 && !isModernFramework) AND NOT (p.inpEstimateMs <= 300) AND (p.inpEstimateMs <= 500)

Deduct 8 points

Poor estimated INP: ~[observed value]ms

When: (p.inpEstimateMs > 0) AND NOT (p.inpEstimateMs <= 200) AND NOT (p.inpEstimateMs <= 500 && !isModernFramework) AND NOT (p.inpEstimateMs <= 300) AND NOT (p.inpEstimateMs <= 500)

Deduct 3 points

Web fonts loaded without preload — causes FOIT/FOUT flash

When: (p.fontPreloadMissed)

Deduct 5 points

Basic analytics only — missing event tracking or tag management

When: NOT (p.analyticsSetupQuality === 'comprehensive') AND NOT (p.analyticsSetupQuality === 'good') AND (p.analyticsSetupQuality === 'basic')

Deduct 6 points

No analytics tracking detected — flying blind on user behavior

When: NOT (p.analyticsSetupQuality === 'comprehensive') AND NOT (p.analyticsSetupQuality === 'good') AND NOT (p.analyticsSetupQuality === 'basic') AND NOT (p.analyticsSetupQuality === 'alternative')

Deduct 5 points

Excessive DOM size ([observed value] elements) — increases memory use and slows rendering

When: (p.domElementCount > 1500)

Deduct 3 points

Inline CSS does not appear minified

When: (!p.cssMinified)

Deduct 3 points

Inline JavaScript does not appear minified

When: (!p.jsMinified)

Deduct 5 points

document.write() used [observed value] time(s) — blocks the parser and delays rendering

When: (p.documentWriteCount > 0)

Deduct 4 points

No efficient cache policy (Cache-Control max-age) on the main document

When: NOT (p.hasEfficientCachePolicy)

Deduct 3 points

[observed value] animated GIF(s) detected — GIFs are far larger than modern video formats

When: (p.animatedGifCount > 0)

Deduct 4 points

[observed value] image(s) lack explicit width/height — a common cause of layout shift (CLS)

When: (p.imagesWithoutDimensions > 0)

Varies

LCP Estimate (Largest Contentful Paint)

lcpEstimateMs is our proxy for the largest above-fold element render time. We estimate from hero image size, font preloading, render-blocking resources, and server timing. Google threshold: ≤2.5s good, ≤4s needs improvement.

Varies

CLS Estimate (Cumulative Layout Shift)

clsEstimate proxies visual stability from images without width/height attributes (imagesWithWidthHeight), font loading strategy, dynamic content injection, and ad placeholders. Google threshold: ≤0.1 good.

Varies

INP Estimate (Interaction to Next Paint)

inpEstimateMs proxies input responsiveness from JavaScript bundle size (totalJsBundleKb), long task script hints (longTaskScriptHints), third-party script count, and main-thread blocking indicators. Google threshold: ≤200ms good.

Varies

HTML Document Size

htmlSizeKb over 100KB indicates bloated markup. Excessive inline styles (inlineStyles) and inline scripts (inlineScripts) inflate document size and delay first render.

Varies

CSS Bundle Size & Optimization

totalCssBundleKb measures all CSS payload. renderBlockingCssCount identifies files blocking first paint. unusedCssHint detects dead CSS. criticalCssDetected rewards above-fold CSS inlining.

Varies

JavaScript Bundle Size & Loading

totalJsBundleKb measures total JS payload. We check asyncScripts, deferScripts vs. renderBlockingScripts ratio. longTaskScriptHints identify scripts likely to cause long tasks (>50ms).

Varies

Image Optimization

hasLazyImages, lazyImageCount, eagerAboveFold (should be 1–3), hasSrcset for responsive images, and hasWebpAvif for modern formats. imageFormats breakdown reveals JPEG/PNG legacy vs. WebP/AVIF modern usage.

Varies

Font Loading Strategy

hasFontDisplay (font-display: swap/optional) prevents FOIT. fontPreloadMissed detects critical fonts not preloaded. variableFontsUsed rewards modern font technology. fontFileCount over 4 indicates excessive font requests.

Varies

Resource Hints (Preconnect/Prefetch/Preload)

hasPreconnect, hasPrefetch, hasPreload, and totalResourceHints measure proactive resource loading. preconnectDomains and preloadTypes (font, script, style) show implementation depth. preloadFontCount validates font preloading.

Varies

Async/Defer Script Optimization

renderBlockingScripts (neither async nor defer) delay parsing. The ratio of asyncScripts + deferScripts to total scripts indicates optimization maturity.

Varies

Third-Party Script Impact

thirdPartyScriptCount and thirdPartyDomains measure external dependency load. Each third-party domain adds DNS lookup, connection, and TLS handshake overhead.

Varies

CDN & Compression

cdnDetected and cdnProvider indicate edge caching. compressionType (br > gzip > none) directly affects transfer size. Brotli compression reduces payloads 15–20% more than gzip.

Varies

Server Response Time (TTFB)

ttfbMs measures time to first byte. Under 200ms is excellent; over 600ms indicates server-side bottlenecks. httpVersion (HTTP/2 or HTTP/3 enables multiplexing).

Varies

Server Timing Headers

serverTimingHeaders expose backend performance metrics (db, cache, render times) for debugging. Their presence signals performance-aware engineering.

Varies

Framework Detection & SPA Analysis

isModernFramework, spaDetected, and jsFrameworkDetected identify React, Next.js, Vue, Angular, etc. SPAs require special SSR/SSG consideration for SEO and initial load performance.

Varies

Analytics Setup Quality

We validate hasGA4Snippet, hasGTMContainer, ga4MeasurementId, hasEventTracking, and compute analyticsSetupQuality. Dual GA4+GTM setup without event tracking wastes data collection potential.

Varies

Image Width/Height Attributes

imagesWithWidthHeight prevents CLS. Images without explicit dimensions cause layout shifts when they load, directly impacting Core Web Vitals CLS score.

Varies

Speculation Rules API · v5.0

We detect <script type="speculationrules">, the modern API that prerenders/prefetches likely next navigations for near-instant page transitions. Its absence is a missed opportunity for perceived-instant navigation on multi-page journeys.

Varies

LCP fetchpriority Hint · v5.0

We check whether any image declares fetchpriority="high". Marking the LCP hero image with fetchpriority="high" lets the browser prioritize it during initial load, directly improving Largest Contentful Paint.

Varies

Image decoding="async" Coverage · v5.0

On pages with 4+ images we measure the share carrying decoding="async". Below 50% coverage, image decode work competes with the main thread. Adding decoding="async" to non-critical images keeps decoding off the main thread.

Varies

modulepreload for ES Modules · v5.0

When ES modules (type="module") are used without <link rel="modulepreload">, the browser discovers dependencies late, creating waterfall latency on the module graph. Preloading critical modules removes that latency.

Varies

Images Without Dimensions · v5.1

Numeric value for images without dimensions. [observed value] image(s) lack explicit width/height — a common cause of layout shift (CLS)

Varies

Animated Gif Count · v5.1

Numeric value for animated gif count. [observed value] animated GIF(s) detected — GIFs are far larger than modern video formats

Varies

Dom Element Count · v5.1

The recorded dom element count value. Excessive DOM size ([observed value] elements) — increases memory use and slows rendering

Varies

Has Efficient Cache Policy · v5.1

Whether the efficient cache policy signal was detected. Efficient cache policy on the document ([observed value])

Varies

Cache Control Value · v5.1

The received Cache-Control header used to explain the cache-policy assessment. The right policy depends on whether content is public or sensitive.

Varies

Css Minified · v5.1

Whether the css minified signal was detected. Inline CSS does not appear minified

Varies

Js Minified · v5.1

Whether the js minified signal was detected. Inline JavaScript does not appear minified

Varies

Document Write Count · v5.1

The recorded document write count value. document.write() used [observed value] time(s) — blocks the parser and delays rendering

Varies

Speed Index Estimate Ms · v5.1

Deterministic Speed Index proxy in milliseconds inferred from source and resource composition. Not a browser paint measurement or field-data result.

Varies

Tti Estimate Ms · v5.1

Deterministic time-to-interactive proxy in milliseconds. It is not measured interactive readiness on a real device.

Varies

Tbt Estimate Ms · v5.1

Deterministic total-blocking-time proxy in milliseconds. It is not measured browser long-task duration.

−2 / 0

High priority lazy image · v5.2

High-priority images should not be lazy-loaded; actual LCP requires a browser measurement. A failure deducts two points; pass, review and not applicable deduct none.

OWASP-mapped web security vulnerability audit visualization — central holographic shield surrounded by hexagonal panels for HTTPS/TLS, exposed secrets, sensitive paths, CORS, DOM-XSS supply chain, and CSP policy checks
OWASP-mapped web security vulnerability audit visualization — central holographic shield surrounded by hexagonal panels for HTTPS/TLS, exposed secrets, sensitive paths, CORS, DOM-XSS supply chain, and CSP policy checks
59 factors evaluated
Current source-derived deductions — 58 conditional rules

The factors below explain grouped concepts, so their deductions vary. These current base-engine rules give the exact conditional amounts. Extension outcomes and coverage checks are documented in the PDF; content-substance caps also apply.

Deduct 25 points

Site does not use HTTPS

When: NOT (p.isHttps)

Deduct 5 points

No HTTP → HTTPS redirect configured

When: NOT (p.isHttps) AND (!s.httpToHttpsRedirect)

Deduct 10 points

Mixed content detected (HTTP resources on HTTPS page)

When: (p.hasMixedContent)

Deduct 10 points

Missing Strict-Transport-Security header

When: NOT (hdrs['strict-transport-security'])

Deduct 10 points

Missing Content-Security-Policy header

When: NOT (hdrs['content-security-policy'])

Deduct 5 points

Missing X-Content-Type-Options header

When: NOT (hdrs['x-content-type-options'])

Deduct 5 points

Missing X-Frame-Options header

When: NOT (hdrs['x-frame-options'])

Deduct 5 points

Missing Referrer-Policy header

When: NOT (hdrs['referrer-policy'])

Deduct 5 points

Missing Permissions-Policy header

When: NOT (hdrs['permissions-policy'])

Deduct 3 points

Conditional deduction; see the exact trigger.

When: NOT (hdrs['cross-origin-opener-policy'])

Deduct 3 points

Conditional deduction; see the exact trigger.

When: NOT (hdrs['cross-origin-resource-policy'])

Deduct 2 points

Conditional deduction; see the exact trigger.

When: NOT (hdrs['cross-origin-embedder-policy'])

Deduct 3 points

Server header exposes technology: [observed value]

When: NOT (!server || server === 'not exposed') AND NOT (isCdnServer)

Deduct 3 points

X-Powered-By header exposes: [observed value]

When: NOT (!poweredBy || poweredBy === 'not exposed') AND NOT (isFrameworkPowered)

Deduct 5 points

[observed value] external links missing rel="noopener noreferrer" — security risk

When: (p.externalLinksWithoutRel > 5)

Deduct 2 points

[observed value] external link(s) without noopener/noreferrer

When: NOT (p.externalLinksWithoutRel > 5) AND (p.externalLinksWithoutRel > 0)

Deduct 3 points

HSTS header present but missing preload directive

When: NOT (p.hstsPreload && p.hstsMaxAge >= 31536000) AND (hdrs['strict-transport-security'] && !p.hstsPreload)

Deduct 3 points

HSTS max-age is only [observed value] days — should be at least 1 year

When: (p.hstsMaxAge > 0 && p.hstsMaxAge < 31536000)

Deduct Math.min(8, uniqueIssueTypes.length * 3) points

Cookie security issues: [observed value]

When: (p.cookieSecurityIssues.length > 0)

Deduct 8 points

[observed value] form(s) submit to insecure HTTP endpoints

When: (p.formActionsInsecure > 0)

Deduct 3 points

No privacy policy detected

When: NOT (p.hasPrivacyPolicy)

Deduct 3 points

No cookie consent banner detected

When: NOT (p.hasCookieConsent)

Deduct 3 points

No Subresource Integrity (SRI) on external scripts

When: NOT (p.hasSubresourceIntegrity) AND (p.thirdPartyScriptCount > 0)

Deduct 6 points

Weak CSP implementation (strictness score: [observed value]/100)

When: (p.cspStrictnessScore > 0) AND NOT (p.cspStrictnessScore >= 70) AND NOT (p.cspStrictnessScore >= 40)

Deduct Math.min(5, p.cspUnsafeInlineCount * 2) points

CSP contains [observed value] unsafe-inline directive(s) — weakens XSS protection

When: (p.cspStrictnessScore > 0) AND (p.cspUnsafeInlineCount > 0 && !p.isModernFramework)

Deduct Math.min(8, p.outdatedLibraryHints.length * 3) points

Outdated libraries detected: [observed value]

When: (p.outdatedLibraryHints.length > 0)

Deduct 8 points

Server-side software version disclosed: [observed value] — enables version-based vulnerability (CVE) lookups

When: (p.frameworkVersionExposed)

Deduct 3 points

Server technology disclosed via response headers/markup: [observed value]

When: (p.serverTechExposed.length > 0) AND (versionless.length > 0 && !p.frameworkVersionExposed)

Deduct 2 points

security.txt found but has issues: [observed value]

When: NOT (p.securityTxtExists && p.securityTxtValid && p.securityTxtIssues.length === 0) AND (p.securityTxtExists && p.securityTxtIssues.length > 0)

Deduct 3 points

security.txt file is missing — no standardized channel for reporting vulnerabilities

When: NOT (p.securityTxtExists && p.securityTxtValid && p.securityTxtIssues.length === 0) AND NOT (p.securityTxtExists && p.securityTxtIssues.length > 0)

Deduct 8 points

Requesting a non-existent path returned HTTP [observed value] (Internal Server Error) instead of a clean 404 — unhandled exception

When: (p.serverErrorDetected)

Deduct Math.min(15, p.errorLeakagePatterns.length * 6) points

Error output leaks sensitive internal details: [observed value]

When: (p.errorLeakagePatterns.length > 0)

Deduct Math.min(12, p.debugInfoLeakage.length * 5) points

Debug/verbose diagnostics exposed: [observed value]

When: (p.debugInfoLeakage.length > 0)

Deduct 15 points

A password/login field submits over an insecure (HTTP) form action — credentials transmitted in clear text

When: (p.passwordFieldInsecureForm)

Deduct 10 points

HTTP Basic Authentication offered over an unencrypted channel (WWW-Authenticate over HTTP) — credentials are base64-encoded, not encrypted

When: (p.basicAuthOverHttp)

Deduct 4 points

[observed value] insecure ws:// WebSocket endpoint(s) referenced — data exchanged unencrypted

When: (p.insecureWebSocketCount > 0)

Deduct 2 points

Legacy X-XSS-Protection header present — deprecated and can introduce vulnerabilities in older browsers

When: (p.xssProtectionLegacy)

Deduct 3 points

Content-Security-Policy is delivered only via a <meta> tag — cannot use report-uri/frame-ancestors and is bypassable

When: (p.cspViaMetaOnly)

Deduct Math.min(6, p.cspMissingDirectives.length * 2) points

CSP is missing key hardening directive(s): [observed value]

When: (p.cspMissingDirectives.length > 0 && (hdrs['content-security-policy'] || p.cspViaMetaOnly))

Deduct 4 points

A sensitive page (login/account/checkout) lacks Cache-Control: no-store — confidential data may be cached by browsers/proxies

When: (p.missingCacheControlOnSensitive)

Deduct 6 points

A session identifier appears to be passed in the URL — session IDs in URLs leak via referrer headers, logs, and browser history

When: (p.sessionIdInUrl)

Deduct 2 points

A password field does not disable autocomplete on a shared/sensitive context — may persist credentials on shared devices

When: (p.autocompleteOnPasswordField)

Deduct Math.min(6, p.stateChangingFormsWithoutCsrf * 3) points

[observed value] state-changing POST form(s) show no visible anti-CSRF token (heuristic — SameSite cookies may still protect them)

When: (p.stateChangingFormsWithoutCsrf > 0)

Deduct Math.min(6, p.dangerousJsSinks.length * 2) points

Dangerous client-side sink(s) detected in inline scripts: [observed value] — potential DOM-based XSS vectors

When: (p.dangerousJsSinks.length > 0)

Deduct 2 points

[observed value] inline event handlers (onclick=, onload=, …) — inline handlers require CSP unsafe-inline and widen the XSS surface

When: (p.inlineEventHandlerCount > 10)

Deduct 2 points

[observed value] javascript: URL(s) found — a legacy XSS/injection vector

When: (p.javascriptUrlCount > 0)

Deduct 3 points

Possible open-redirect parameter(s) in links: [observed value] — can be abused for phishing (CWE-601)

When: (p.openRedirectParams.length > 0)

Deduct Math.min(8, p.untrustedCrossDomainScripts.length * 4) points

[observed value] script(s) loaded from higher-risk / abandoned third-party origins (e.g. [observed value]) — supply-chain risk

When: (p.untrustedCrossDomainScripts.length > 0)

Deduct Math.min(40, p.exposedSecrets.length * 20) points

Possible secret/API key pattern(s) exposed in page source: [observed value] — CRITICAL if these are live credentials (CWE-798)

When: (p.exposedSecrets.length > 0)

Deduct Math.min(30, p.exposedSensitivePaths.length * 15) points

Sensitive path(s) publicly accessible: [observed value] — may expose source control, environment secrets or internals

When: (p.exposedSensitivePaths.length > 0)

Deduct 8 points

Directory listing appears enabled — file/folder structure is browsable by anyone

When: (p.directoryListingDetected)

Deduct Math.min(8, highRisk.length * 4) points

Potentially dangerous HTTP method(s) advertised: [observed value] — TRACE/TRACK enable XST and PUT/DELETE may allow unauthorized changes

When: (p.dangerousHttpMethods.length > 0) AND (highRisk.length > 0)

Deduct 2 points

robots.txt discloses sensitive-looking path(s): [observed value] — Disallow entries can act as a map for attackers

When: (p.robotsSensitivePaths.length > 0)

Deduct Math.min(4, p.htmlCommentLeaks.length * 2) points

HTML comments leak potentially sensitive hints: [observed value]

When: (p.htmlCommentLeaks.length > 0)

Deduct 4 points

A private/internal IP address (RFC 1918) is disclosed in the page source — reveals internal network topology

When: (p.privateIpDisclosure && p.privateIpDisclosure.length > 0)

Deduct 10 points

CORS reflects the request Origin while allowing credentials — effectively allows any site to make authenticated cross-origin requests

When: (p.corsReflectedWithCredentials)

Deduct 5 points

Access-Control-Allow-Origin: * — the API is readable by any website

When: NOT (p.corsReflectedWithCredentials) AND (p.corsWildcard)

Deduct Math.min(4, p.iframeSandboxMissing * 2) points

[observed value] untrusted <iframe>(s) without a sandbox attribute — embedded content runs with full privileges

When: (p.iframeSandboxMissing > 0)

Varies

HTTPS Encryption

isHttps verifies TLS encryption. Without HTTPS, browsers display "Not Secure" warnings, forms transmit data in plaintext, and Google applies a ranking penalty.

Varies

Mixed Content

hasMixedContent detects HTTP resources loaded on HTTPS pages. Browsers may block these resources, breaking functionality and displaying security warnings.

Varies

HSTS (Strict-Transport-Security)

HSTS forces HTTPS-only connections. We check hstsMaxAge (≥ 31536000 recommended) and hstsPreload (inclusion in browser preload lists for zero-trust-on-first-use protection).

Varies

Content-Security-Policy (CSP)

CSP is the primary defense against XSS attacks. A missing CSP leaves your site vulnerable to injected scripts that can steal cookies, credentials, and user data.

Varies

CSP Strictness Score

cspStrictnessScore (0–100) evaluates directive count, cspUsesNonce vs. cspUnsafeInlineCount, frame-ancestors restrictions, and default-src fallbacks. Nonce-based CSP is significantly stronger than unsafe-inline.

Varies

Permissions-Policy Depth

permissionsPolicyFeatures and permissionsPolicyDepth measure how many browser APIs (camera, microphone, geolocation, payment) are explicitly restricted. Without this header, any embedded iframe can access sensitive device features.

Varies

X-Content-Type-Options

The nosniff directive in headers prevents MIME-type sniffing attacks where browsers misinterpret file types, potentially executing malicious content.

Varies

X-Frame-Options

Prevents clickjacking by controlling iframe embedding. DENY or SAMEORIGIN values stop malicious sites from framing your pages.

Varies

Referrer-Policy

Controls how much URL information leaks via the Referer header. strict-origin-when-cross-origin balances analytics needs with privacy.

Varies

Cross-Origin Policies (COOP/CORP/COEP)

hasCorsHeaders and cross-origin isolation headers protect against Spectre side-channel attacks by isolating your page's browsing context from cross-origin resources.

Varies

Outdated Library Detection

jqueryVersion and outdatedLibraryHints detect libraries with known CVEs: jQuery <3.5 (XSS), Angular <1.8 (sandbox escapes), Bootstrap <5 (XSS via data attributes).

Varies

Cookie Security

cookieSecurityIssues identifies cookies without Secure (sent over HTTP), HttpOnly (accessible to JavaScript), and SameSite (vulnerable to CSRF) attributes.

Varies

Insecure Form Actions

formActionsInsecure counts forms submitting to HTTP endpoints, transmitting user data in plaintext — a PCI-DSS and GDPR violation.

Varies

Subresource Integrity (SRI)

hasSubresourceIntegrity and sriCount verify that external scripts include integrity hashes, preventing supply-chain attacks where CDN-hosted scripts are modified.

Varies

External Link Security

externalLinksWithoutRel counts links with target="_blank" but missing rel="noopener noreferrer", enabling reverse tabnabbing attacks.

Varies

Privacy Policy & Cookie Consent

hasPrivacyPolicy and hasCookieConsent are GDPR/CCPA legal requirements. Non-compliance can result in fines up to 4% of annual global revenue.

Varies

Rate Limiting

hasRateLimitHeaders (X-RateLimit-*, Retry-After) indicate protection against brute-force attacks, credential stuffing, and API abuse.

Varies

Server/Technology Exposure

headers like Server, X-Powered-By, and X-AspNet-Version expose your technology stack, giving attackers a targeted roadmap of known vulnerabilities.

Varies

Framework / Server Version Disclosure

frameworkVersionExposed detects a specific software version leaked in the Server or X-Powered-By header or the generator meta tag (e.g. "nginx/1.18.0", "PHP/7.4.3", "WordPress 5.9"). A precise version lets an attacker look up the exact list of published CVEs affecting your stack — the single highest-value fingerprint for targeted exploitation.

Varies

Technology Fingerprint Exposure

serverTechExposed aggregates every technology-revealing signal in your headers and markup (Server, X-Powered-By, X-AspNet-Version, X-Generator, framework-specific cookies and comment signatures). Even without a version number, each fingerprint narrows the attacker's search space and enables stack-specific attacks.

Varies

security.txt Vulnerability Disclosure (RFC 9116)

We fetch /.well-known/security.txt and validate it per RFC 9116 (securityTxtPresent, securityTxtLocation, securityTxtIssues). A valid, future-dated file with a Contact and Expires field gives ethical researchers a standardized channel to report vulnerabilities responsibly instead of disclosing them publicly.

Varies

Internal Server Error Probe (5xx Handling)

We request a deliberately non-existent path and inspect the response (errorProbeStatusCode). A clean 404 is correct; a 500-class Internal Server Error on a missing route signals an unhandled exception that can leak internal state and indicates fragile error handling.

Varies

Error & Stack Trace Leakage

errorLeakagePatterns scans responses for exposed stack traces, absolute file paths, SQL fragments, and framework debug output. Leaked traces hand attackers a map of your file system, framework internals, and query structure — one of the most damaging low-effort information disclosures (CWE-209).

Varies

Debug & Verbose Diagnostics Exposure

debugInfoLeakage detects debug mode left enabled in production: profiler toolbars, verbose diagnostic headers, and development-only banners. Debug output erodes the defense-in-depth "security by obscurity" layer and frequently reveals environment variables and internal routes.

Varies

Email Address Harvesting Exposure

exposedEmails / exposedEmailCount surface raw email addresses printed in the page source. Intentional contact addresses are informational only, but unprotected mailto and inline addresses are trivially scraped by spam and phishing bots — obfuscation or a contact form is recommended.

Varies

Exposed Secrets & API Keys · v4.9.1

exposedSecrets scans inline scripts and markup for high-signal credential patterns (AWS access keys, Stripe live keys, Google API keys, GitHub/Slack tokens, JWTs, SendGrid keys, private-key blocks and inline Firebase config). Hard-coded live credentials in client-side code are a critical CWE-798 exposure — anyone can read and abuse them. Maps to OWASP A07.

Varies

Publicly Accessible Sensitive Paths · v4.9.1

exposedSensitivePaths performs non-destructive GET probes of common leak points (/.git/config, /.env, /.svn/entries, /.DS_Store, /server-status) with content-based confirmation. Exposed VCS folders or environment files can hand attackers your entire source and secrets (CWE-538/CWE-548, OWASP A05).

Varies

Password Field on Insecure Form · v4.9.1

passwordFieldInsecureForm flags any form containing a password input whose action resolves to http://. Credentials are then transmitted in clear text and trivially intercepted (CWE-319, ASVS 9.1, OWASP A02).

Varies

CORS Reflected Origin with Credentials · v4.9.1

corsReflectedWithCredentials detects Access-Control-Allow-Credentials: true combined with a reflected or wildcard Origin — effectively letting any website make authenticated cross-origin requests to your API (CWE-942/CWE-346, OWASP A05).

Varies

CORS Wildcard Origin · v4.9.1

corsWildcard flags Access-Control-Allow-Origin: *, which makes API responses readable by any site. A strict server-side origin allowlist is recommended.

Varies

HTTP Basic Auth over HTTP · v4.9.1

basicAuthOverHttp detects a WWW-Authenticate: Basic challenge served over an unencrypted channel. Basic-Auth credentials are only base64-encoded, so they are effectively sent in the clear (CWE-319).

Varies

Directory Listing Enabled · v4.9.1

directoryListingDetected identifies auto-generated index pages that expose your file/folder structure to anyone. Disable autoindex / Options -Indexes (CWE-548, OWASP A05).

Varies

Dangerous HTTP Methods · v4.9.1

dangerousHttpMethods inspects the OPTIONS Allow header for TRACE/TRACK (enable Cross-Site Tracing) and PUT/DELETE/CONNECT/PATCH (may allow unauthorized modification). Only the verbs your app needs should be enabled (CWE-650).

Varies

DOM-XSS Sinks in Inline Scripts · v4.9.1

dangerousJsSinks detects risky client-side sinks (eval, document.write, innerHTML assignment, Function(), setTimeout with a string, insertAdjacentHTML). Combined with untrusted input these are classic DOM-based XSS vectors (CWE-79, OWASP A03).

Varies

Untrusted / Abandoned Third-Party Scripts · v4.9.1

untrustedCrossDomainScripts flags scripts loaded from higher-risk or historically compromised CDNs (e.g. polyfill-style hosts). Supply-chain compromise of a single script can run arbitrary code on every page (CWE-1104/CWE-829, OWASP A08).

Varies

Software Composition Inventory (SBOM) · v4.9.1

scriptInventoryCount and detectedLibraries catalogue every script resource and fingerprinted client-side library, giving you a lightweight software bill of materials to cross-reference against known CVEs.

Varies

Session ID in URL · v4.9.1

sessionIdInUrl detects session-token-like parameters in URLs. Session IDs in URLs leak through Referer headers, server logs, and browser history and enable session fixation (CWE-598/CWE-384, ASVS 3.x).

Varies

Anti-CSRF Token Heuristic · v4.9.1

stateChangingFormsWithoutCsrf counts state-changing POST forms that show no visible anti-CSRF token (search forms excluded). This is a low-confidence heuristic — SameSite cookies may still protect them — but missing tokens warrant review (CWE-352, OWASP A01).

Varies

Open Redirect Parameters · v4.9.1

openRedirectParams inspects links for redirect/return/next/url parameters carrying absolute URLs, a common phishing pivot when unvalidated (CWE-601).

Varies

Insecure WebSocket (ws://) · v4.9.1

insecureWebSocketCount finds unencrypted ws:// endpoints in markup/scripts. WebSocket traffic should always use the encrypted wss:// scheme (CWE-319).

Varies

CSP Delivered via <meta> Only · v4.9.1

cspViaMetaOnly flags a policy delivered only through a meta tag, which cannot enforce frame-ancestors or report-uri and is easier to bypass. Serve the CSP as an HTTP header.

Varies

CSP Missing Hardening Directives · v4.9.1

cspMissingDirectives checks for absent object-src, base-uri and frame-ancestors directives — common gaps that leave known CSP bypasses open.

Varies

Sensitive-Page Cache-Control · v4.9.1

missingCacheControlOnSensitive verifies login/account/checkout pages send Cache-Control: no-store so confidential data is not cached by browsers or shared proxies (CWE-525, ASVS 8.2).

Varies

Untrusted iframe Without sandbox · v4.9.1

iframeSandboxMissing counts iframes embedding third-party origins without a sandbox attribute, meaning embedded content runs with full privileges.

Varies

HTML Comment & Private-IP Leakage · v4.9.1

htmlCommentLeaks scans developer comments for TODOs, credentials, internal URLs and debug notes; privateIpDisclosure flags RFC 1918 internal IPs in the source — both reveal internal details useful to attackers (CWE-200).

Varies

robots.txt Sensitive-Path Disclosure · v4.9.1

robotsSensitivePaths surfaces admin/private Disallow entries that act as a roadmap for attackers. Protect sensitive paths with authentication rather than obscurity.

Varies

Legacy X-XSS-Protection & Inline Handlers · v4.9.1

xssProtectionLegacy flags the deprecated X-XSS-Protection header (can introduce bugs in old browsers); inlineEventHandlerCount and javascriptUrlCount measure inline on*= handlers and javascript: URLs that force CSP unsafe-inline and widen the XSS surface.

Varies

Authentication Surface Detection · v4.9.1

hasLoginForm and hasPasswordResetForm identify authentication entry points so the report can recommend rate limiting, MFA, and single-use time-limited reset tokens (OWASP A07). Positive signals: cspHasReporting, clearSiteDataSupported and crossOriginIsolated (COOP+COEP) are recognised as hardening wins.

Varies

A01:2025 · Broken Access Control & SSRF · v5.0

A light, non-destructive probe checks whether a privileged/admin path (e.g. /admin, /dashboard, /api/admin) is reachable with real admin markup and no auth challenge. We also flag IDOR-prone direct object references in links and SSRF-style references to cloud instance-metadata endpoints (169.254.169.254). Recommendation references centralized, deny-by-default authorization (OPA / Casbin) and ASVS L2 access-control verification.

Varies

A02:2025 · Security Misconfiguration & Source-Map Exposure · v5.0

Probes for publicly readable debug/diagnostic endpoints (phpinfo, Spring Boot /actuator, Symfony /_profiler) and publicly served JavaScript source maps that leak original source. Recommendation references hardened, environment-specific configuration baselines and disabling source maps in production.

Varies

A03:2025 · Software Supply Chain Failures · v5.0

Probes for exposed dependency manifests / lockfiles (package.json, composer.json, yarn.lock, Gemfile.lock), measures the Subresource-Integrity coverage ratio across cross-origin scripts (distinct from mere SRI presence), and detects a published SBOM (CycloneDX / SPDX). Recommendation references SLSA provenance and signed, pinned dependencies.

Varies

A04:2025 · Cryptographic Failures · v5.0

Detects weak-hash usage (MD5 / SHA-1) in client scripts and sensitive PII form fields submitted in cleartext over HTTP. Recommendation references modern algorithms (SHA-256+/Argon2/bcrypt) and TLS-only transmission of sensitive data.

Varies

A05:2025 · Injection · v5.0

Flags raw-HTML binding sinks (React dangerouslySetInnerHTML, Vue v-html), production GraphQL introspection (light probe), and Markdown rendering without a sanitizer. Recommendation references context-aware output encoding and DOMPurify-style sanitization.

Varies

A06:2025 · Insecure Design · v5.0

Detects high-value forms (login, signup, password reset, contact) with no anti-automation challenge (CAPTCHA/Turnstile/hCaptcha) and file-upload inputs without type/size constraints. Recommendation references threat modeling and abuse-case-driven design.

Varies

A07:2025 · Authentication Failures · v5.0

Checks for the absence of a phishing-resistant factor (WebAuthn / passkey / TOTP MFA), missing autocomplete tokens on identifier fields, and session cookies lacking the __Host- / __Secure- prefix. Recommendation references passkey adoption and hardened session cookies.

Varies

A08:2025 · Software & Data Integrity Failures · v5.0

Flags dynamically-injected remote scripts loaded without integrity verification and opaque serialized state passed in URL parameters (deserialization/tampering risk). Recommendation references signed updates and integrity-verified pipelines.

Varies

A09:2025 · Security Logging & Alerting Failures · v5.0

Detects the presence/absence of client-side error & security monitoring (Sentry, Datadog RUM, Bugsnag, Rollbar). Absence is surfaced as a recommendation to add tamper-evident, centrally-aggregated monitoring and alerting.

Varies

A10:2025 · Mishandling of Exceptional Conditions · v5.0

A random non-existent path is probed; a soft-404 / fail-open response (HTTP 200 for an unknown route) signals exceptional conditions handled insecurely. Recommendation references fail-closed error handling and correct status semantics.

−2 / 0

Canonical credentials · v5.2

Canonical must not expose URL credentials. A failure deducts two points; pass, review and not applicable deduct none.

Futuristic artificial intelligence neural network with glowing synapses, connected document nodes, and schema markup visualization
Futuristic artificial intelligence neural network with glowing synapses, connected document nodes, and schema markup visualization
21 factors evaluated
Current source-derived deductions — 0 conditional rules

The factors below explain grouped concepts, so their deductions vary. These current base-engine rules give the exact conditional amounts. Extension outcomes and coverage checks are documented in the PDF; content-substance caps also apply.

Varies

Structured Data for AI

hasSchemaOrg and schemaTypes provide machine-readable context. Without structured data, AI must infer meaning from unstructured HTML — a lossy process that reduces citation accuracy.

Varies

AI Crawler Governance (robots.txt)

We check 12+ AI crawlers (GPTBot, ClaudeBot, PerplexityBot, Google-Extended, Amazonbot, Bytespider, etc.) across both meta tags (aiCrawlerBlocked) and robots.txt (robotsTxtAiCrawlerRules). additionalAiCrawlersAllowed and additionalAiCrawlersBlocked provide granular per-crawler governance.

Varies

Robots.txt Deep Analysis

robotsTxtExists is foundational. We parse robotsTxtSitemapRefs (sitemap declarations), robotsTxtBlocksAssets (CSS/JS blocking hurts rendering), and robotsTxtBlocksAll (Disallow: / blocks everything).

Varies

llms.txt File Existence

Absence receives no penalty. Google AI features do not require a special AI text file. If supplied, its content can be reviewed as optional documentation.

Varies

llms-full.txt Companion File

llmsFullTxtExists checks for /llms-full.txt, the extended version containing comprehensive content for deep AI ingestion. Together, llmsTxtByteSize and llmsFullTxtByteSize indicate content depth.

Varies

llms.txt Structure & Sections

llmsTxtSectionCount measures document organization. llmsTxtHasStructuredSections and llmsTxtHasMarkdownFormatting indicate proper Markdown structure that AI parsers can reliably extract.

Varies

llms.txt Metadata Quality

llmsTxtHasTitle, llmsTxtHasDescription, llmsTxtHasVersionOrDate, and llmsTxtHasCanonicalDomain provide essential metadata that helps AI models understand your organization and content currency.

Varies

llms.txt URL Inventory

llmsTxtHasUrlList and llmsTxtUrlCount indicate how many pages you've indexed for AI consumption. llmsTxtBrokenUrlPatterns detects URLs in llms.txt that appear malformed or incomplete.

Varies

llms.txt Service & API Documentation

llmsTxtHasServiceList and llmsTxtHasApiDocs signal that you've documented your offerings in a format AI agents can parse for tool-use and function-calling scenarios.

Varies

llms.txt Legal & Citation Framework

llmsTxtHasLicenseOrTerms, llmsTxtHasPreferredCitation, and llmsTxtHasContentGuidelines establish how AI models should attribute and use your content — critical for responsible AI adoption.

Varies

llms.txt Contact & Discovery

llmsTxtHasContactInfo provides a feedback channel for AI developers. llmsTxtHasLinkToFull connects the summary to the full version. llmsTxtLinkedFromHtml and llmsTxtLinkedFromRobotsTxt measure discoverability.

Varies

llms.txt Overall Quality Score

llmsTxtOverallScore (0–100) is our composite assessment. llmsTxtIssues and llmsTxtRecommendations provide actionable feedback for improving your llms.txt implementation.

Varies

RAG-Friendliness Score

ragFriendlinessScore (0–100) measures how well content can be chunked for vector embedding. headingsWithIds and sectionAnchorsCount enable precise chunk targeting in Retrieval-Augmented Generation pipelines.

Varies

Content Provenance Signals

hasProvenanceSignals detects attributions like "according to [source]" and "our research found" that make claims verifiable and citation-worthy for AI systems.

Varies

Semantic HTML Elements

semanticElementCount vs. nonSemanticDivCount ratio reveals structural clarity. semanticElements (article, section, aside, figure, main, nav) provide meaning AI can parse without heuristics.

Varies

FAQ/Q&A Content Patterns

faqCount, hasQAPattern, and definitionLists detect question-answer content — the most extractable format for AI citation and knowledge graph population.

Varies

Freshness Signals

dateModified, datePublished, hasFreshnessSignals, and contentFreshnessSignal ("fresh"/"aging"/"stale") measure how current your content appears to AI models.

Varies

Social Links & Entity Signals

hasSocialLinks and socialPlatforms help AI confirm your brand's entity identity in the Knowledge Graph, improving entity disambiguation accuracy.

Varies

HTML-to-Text Ratio

htmlToTextRatio below 10% indicates markup-heavy, content-light pages. A 20–70% ratio indicates content-rich pages that AI models can meaningfully process.

Varies

JS Content Dependency

jsContentRatio measures how much content requires JavaScript to render. AI crawlers generally do not execute JS, so high ratios mean AI sees an empty page.

Varies

Descriptive Alt Text for Multimodal AI · v5.0

On pages with 3+ images we measure the share whose alt text is genuinely descriptive (≥15 characters). Below 50%, multimodal models cannot understand or cite your imagery. Rich, standalone alt text makes images machine-interpretable for AI systems that reason over pictures.

AI Optimization (AIO) content-quality visualization — holographic neural core linking document nodes, citation sparkles, and entity-knowledge triples that make a page valuable for AI model training and citation
AI Optimization (AIO) content-quality visualization — holographic neural core linking document nodes, citation sparkles, and entity-knowledge triples that make a page valuable for AI model training and citation
14 factors evaluated
Current source-derived deductions — 21 conditional rules

The factors below explain grouped concepts, so their deductions vary. These current base-engine rules give the exact conditional amounts. Extension outcomes and coverage checks are documented in the PDF; content-substance caps also apply.

Deduct 8 points

Content may be too thin for AI optimization ([observed value] words)

When: NOT (p.wordCount >= 1500) AND NOT (p.wordCount >= 600) AND (p.wordCount >= 300)

Deduct 15 points

Very thin content ([observed value] words)

When: NOT (p.wordCount >= 1500) AND NOT (p.wordCount >= 600) AND NOT (p.wordCount >= 300)

Deduct 10 points

No structured Q&A content

When: NOT (p.faqCount > 3) AND NOT (p.faqCount > 0)

Deduct 8 points

Weak entity markup — few terms emphasized

When: NOT (p.entityMentions.length >= 10) AND NOT (p.entityMentions.length >= 3)

Deduct 8 points

Low semantic markup ratio — [observed value] divs vs [observed value] semantic elements

When: NOT (semanticRatio > 8)

Deduct 5 points

Conditional deduction; see the exact trigger.

When: NOT (p.listCount >= 3 || p.tableCount >= 1)

Deduct 8 points

Weak E-E-A-T schema signals

When: NOT (eeatSchemas >= 2)

Deduct 5 points

Paragraphs are too long for optimal AI consumption

When: NOT (p.avgWordsPerParagraph > 0 && p.avgWordsPerParagraph <= 30) AND (p.avgWordsPerParagraph > 40)

Deduct 3 points

Conditional deduction; see the exact trigger.

When: NOT (p.hasSpeakableSchema)

Deduct 5 points

No external citations/references — reduces credibility for AI models

When: NOT (p.citationCount >= 5) AND NOT (p.citationCount >= 1)

Deduct 4 points

Conditional deduction; see the exact trigger.

When: NOT (p.statisticCount >= 5) AND (p.statisticCount === 0)

Deduct 2 points

Conditional deduction; see the exact trigger.

When: NOT (p.quoteCount >= 2)

Deduct 3 points

Conditional deduction; see the exact trigger.

When: NOT (p.hasExpertiseSignals) AND (p.hasAuthorInfo)

Deduct 6 points

No author or expertise signals

When: NOT (p.hasExpertiseSignals) AND NOT (p.hasAuthorInfo)

Deduct 2 points

Conditional deduction; see the exact trigger.

When: NOT (p.clearCtaCount >= 3) AND (p.clearCtaCount >= 1)

Deduct 5 points

No clear call-to-action elements detected

When: NOT (p.clearCtaCount >= 3) AND NOT (p.clearCtaCount >= 1)

Deduct 3 points

No CTA above the fold

When: NOT (p.hasAboveFoldCta)

Deduct 3 points

Low form usability score ([observed value]/100) — may reduce form completions

When: NOT (p.formCount > 0 && p.formUsabilityScore >= 80) AND (p.formCount > 0 && p.formUsabilityScore < 60)

Deduct 4 points

Insufficient trust signals for conversion optimization

When: NOT (p.hasTrustSignals)

Deduct 3 points

No social proof elements

When: NOT (p.hasSocialProof)

Deduct 3 points

No clear value proposition in headings

When: NOT (p.hasValueProposition)

Varies

Content Depth (Word Count)

wordCount under 300 triggers thinContentSignal. Pages over 1,500 words are 3× more likely to appear in AI-generated responses due to topical comprehensiveness.

Varies

Structured Q&A Content

faqCount and hasQAPattern detect question-answer formatting — the highest-value content pattern for AI citation, directly matching user query intent.

Varies

Entity Markup Strength

entityMentions and strong/em/mark tags highlight key entities. entitySalienceScore measures how prominently entities appear, helping AI extract knowledge triples.

Varies

E-E-A-T Schema Signals

hasPersonSchema, hasArticleSchema, hasReviewSchema, and hasServiceSchema provide machine-readable E-E-A-T signals that AI models use to assess content authority.

Varies

CTA Elements & Above-Fold CTA

clearCtaCount and hasAboveFoldCta measure conversion optimization. formUsabilityScore evaluates form UX. Three or more CTAs with action-oriented text indicate a mature conversion funnel.

Varies

Trust Signals & Social Proof

hasTrustSignals, trustSignalTypes, hasSocialProof, and hasTrustBadges evaluate conversion confidence signals — testimonials, trust badges, client logos, and review counts.

Varies

Citation Readiness

citationCount (5+ external citations), quoteCount (blockquote elements), and originalDataSignals demonstrate research depth that AI models prefer to cite.

Varies

Statistics/Data Point Density

statisticCount measures concrete numbers and percentages in content. Data-rich content reads as authoritative analysis rather than opinion, increasing AI citation probability.

Varies

Author/Expertise Signals

hasAuthorInfo, hasExpertiseSignals, and hasAuthorBox provide visible accountability. uniqueInsightPatterns detect phrases like "our research found" signaling first-hand expertise.

Varies

Urgency & Value Proposition

hasUrgencyElements (limited-time offers, countdown timers) and hasValueProposition (clear benefit statements) are conversion accelerators that indicate commercial intent optimization.

Varies

Speakable Schema

hasSpeakableSchema tells voice assistants which page sections are suitable for text-to-speech, optimizing for the growing voice search channel.

Varies

Value Proposition in Headings

H1 should clearly communicate what you offer, for whom, and why it matters. We check for benefit-oriented language patterns in heading text.

Varies

Named-Entity Consistency · v5.0

We extract the primary entity/brand token from the <title>, the H1, and the schema "name" property, then verify all three resolve to the same entity. Inconsistent naming across these three anchors forces AI systems to guess your identity; aligning them yields a single, unambiguous entity for citation and knowledge-graph resolution.

−2 / 0

Main snippet exclusion · v5.2

Review whether all main content is excluded from search snippets. A failure deducts two points; pass, review and not applicable deduct none.

Futuristic inclusive digital accessibility interface showing universal accessibility symbols as glowing holographic icons connected by light beams
Futuristic inclusive digital accessibility interface showing universal accessibility symbols as glowing holographic icons connected by light beams
19 factors evaluated
Current source-derived deductions — 21 conditional rules

The factors below explain grouped concepts, so their deductions vary. These current base-engine rules give the exact conditional amounts. Extension outcomes and coverage checks are documented in the PDF; content-substance caps also apply.

Deduct 10 points

Missing lang attribute on <html>

When: NOT (p.hasLangAttr)

Deduct 8 points

No skip navigation link

When: NOT (p.hasSkipNav)

Deduct missing.length * 4 points

Missing landmarks: [observed value]

When: NOT (landmarksPresent.length === 3)

Deduct Math.min(15, p.imagesWithoutAlt * 2) points

[observed value] of [observed value] images ([observed value]%) missing alt text

When: NOT (p.imageCount > 0 && p.imagesWithoutAlt === 0) AND (p.imagesWithoutAlt > 0)

Deduct 8 points

[observed value] form(s) missing proper labels

When: NOT (p.formCount > 0 && p.formsWithoutLabels === 0) AND (p.formsWithoutLabels > 0)

Deduct 5 points

[observed value] iframe(s) missing title

When: NOT (p.iframeCount > 0 && p.iframesWithTitle >= p.iframeCount) AND (p.iframeCount > 0 && p.iframesWithTitle < p.iframeCount)

Deduct Math.min(8, unlabeled * 2) points

[observed value] button(s) missing accessible labels

When: NOT (p.buttonCount > 0 && p.buttonsWithLabel >= p.buttonCount) AND (p.buttonCount > 0 && p.buttonsWithLabel < p.buttonCount)

Deduct 5 points

No ARIA attributes detected

When: NOT (p.ariaCount > 10) AND NOT (p.ariaCount > 0)

Deduct 4 points

Heading hierarchy has gaps — confusing for screen readers

When: (p.headingGaps.length > 0)

Deduct 8 points

No focus styles detected

When: NOT (p.hasFocusStyles)

Deduct 3 points

Deprecated HTML tags impact accessibility

When: (p.deprecatedTags.length > 0)

Deduct 5 points

Potential contrast issues: [observed value]

When: (p.colorContrastHints.length > 0)

Deduct 6 points

[observed value] HTML validity issues detected — affects assistive technology parsing

When: (p.htmlNestingErrors.length > 5)

Deduct 3 points

[observed value] minor HTML validity issue(s)

When: NOT (p.htmlNestingErrors.length > 5) AND NOT (p.htmlNestingErrors.length > 0 && p.htmlNestingErrors.length <= 5 && p.isModernFramework) AND (p.htmlNestingErrors.length > 0)

Deduct 5 points

[observed value] images missing explicit dimensions — causes layout shifts for screen reader users

When: (p.imageCount > 3 && p.imagesWithWidthHeight < p.imageCount * 0.5)

Deduct 5 points

[observed value] table(s) missing <th> header cells — screen readers cannot identify column/row context

When: (p.tablesWithoutHeaders > 0)

Deduct 8 points

[observed value] video(s) missing captions/subtitles

When: (p.videosWithoutCaptions > 0)

Deduct 5 points

CAPTCHA detected without accessible alternative

When: (p.hasCaptcha && !p.captchaHasAlternative)

Deduct Math.min(6, p.emptyButtonCount * 2) points

[observed value] button(s) with no accessible label

When: (p.emptyButtonCount > 0)

Deduct 5 points

[observed value] focusable element(s) inside aria-hidden containers

When: (p.ariaHiddenOnFocusable > 0)

Deduct Math.min(6, p.duplicateIds * 2) points

[observed value] duplicate ID(s) — breaks ARIA references and label associations

When: (p.duplicateIds > 0)

Varies

Language Declaration (lang)

hasLangAttr and htmlLang are parsed by screen readers to select the correct speech synthesis voice. Without lang, every word may be mispronounced. hasLangOnParts detects partial language declarations for multilingual content.

Varies

Skip Navigation Link

hasSkipNav allows keyboard-only users to bypass navigation menus (often 20+ links) and jump directly to main content.

Varies

Semantic Landmarks

hasMainLandmark, hasNavLandmark, and hasFooterLandmark enable screen reader users to navigate by page regions using shortcut keys.

Varies

Image Alt Text

imagesWithoutAlt renders images invisible to screen readers. imagesWithEmptyAlt (alt="") is valid only for decorative images — informative images require descriptive text.

Varies

Form Labels & Usability

formsWithoutLabels vs. formsWithLabels ratio determines form accessibility. formErrorIdentification checks that error messages are associated with their respective fields.

Varies

Focus Styles

hasFocusStyles verifies visible focus indicators — the only way keyboard users can track their position on the page. Custom :focus-visible styles are preferred over browser defaults.

Varies

ARIA Implementation

hasAria, ariaCount, and ariaRoles provide accessibility metadata for custom interactive elements. ariaHiddenOnFocusable detects the critical error of hiding focusable elements from screen readers.

Varies

Button Labels

emptyButtonCount counts buttons without text content or aria-label. These are announced as just "button" with no context, making navigation impossible.

Varies

Color Contrast

contrastIssueCount and colorContrastHints detect WCAG 1.4.3 violations. 4.5:1 contrast ratio is required for normal text, 3:1 for large text (18px+).

Varies

Video Captions

videosWithoutCaptions excludes 466 million people worldwide with hearing loss and misses indexable text content for SEO.

Varies

CAPTCHA Accessibility

hasCaptcha without captchaHasAlternative (audio or logic-based) completely blocks blind users from completing forms.

Varies

Duplicate IDs

duplicateIds break ARIA references (aria-labelledby, aria-describedby) and form label associations, causing assistive technology failures.

Varies

HTML Validity / Nesting Errors

htmlNestingErrors (e.g., <p> inside <p>, interactive elements inside <a>) cause assistive technology parsing failures and unpredictable behavior.

Varies

Tables & Iframes

tablesWithoutHeaders (missing <th>) make data tables unnavigable by screen readers. tablesWithCaption rewards properly described tables. iframesWithTitle vs. iframeCount measures embedded content accessibility.

Varies

Tab Index Management

tabindexCount and negativeTabindex audit keyboard navigation order. Negative tabindex removes elements from tab order; excessive positive values create confusing navigation sequences.

Varies

Text Spacing Overrides (WCAG 2.2 1.4.12) · v5.0

We scan inline styles for line-height, letter-spacing, or word-spacing locked with !important. Locking spacing blocks users who apply custom stylesheets or spacing bookmarklets to improve readability, violating WCAG 2.2 Success Criterion 1.4.12 Text Spacing.

Varies

Forced-Colors / High-Contrast Support · v5.0

We check for @media (forced-colors), prefers-contrast, or -ms-high-contrast handling. Without it, Windows High Contrast / forced-colors users may lose essential UI (icons, borders, focus rings) that rely on background images or removed color.

Varies

Consistent Help Mechanism (WCAG 2.2 3.2.6) · v5.0

We detect a discoverable help affordance (contact/help/support link). WCAG 2.2 Success Criterion 3.2.6 requires help access to appear in a consistent location across pages so users with cognitive disabilities can reliably find assistance.

−2 / 0

Aria labelledby targets · v5.2

Every aria-labelledby reference must resolve to an existing element. A failure deducts two points; pass, review and not applicable deduct none.

Futuristic holographic globe with AI search engines orbiting, data streams flowing between continents for Generative Engine Optimization
Futuristic holographic globe with AI search engines orbiting, data streams flowing between continents for Generative Engine Optimization
15 factors evaluated
Current source-derived deductions — 17 conditional rules

The factors below explain grouped concepts, so their deductions vary. These current base-engine rules give the exact conditional amounts. Extension outcomes and coverage checks are documented in the PDF; content-substance caps also apply.

Deduct 10 points

No direct Q&A patterns for generative AI extraction

When: NOT (p.hasQAPattern)

Deduct 8 points

No data tables for AI comparison extraction

When: NOT (p.tableCount >= 1)

Deduct 5 points

Few or no lists

When: NOT (p.listCount >= 5) AND NOT (p.listCount >= 2)

Deduct 5 points

Conditional deduction; see the exact trigger.

When: NOT (p.hasHowToPattern)

Deduct 3 points

Conditional deduction; see the exact trigger.

When: NOT (p.definitionLists > 0)

Deduct 10 points

Content too thin for AI citation value

When: NOT (p.wordCount >= 1000) AND (p.wordCount < 500)

Deduct 5 points

Conditional deduction; see the exact trigger.

When: NOT (p.entityMentions.length >= 8)

Deduct 5 points

Insufficient structured data for generative engine context

When: NOT (p.schemaCount >= 2)

Deduct 3 points

hint

When: (p.contentReadabilityHints.length > 0) AND (hint.includes('too long'))

Deduct 5 points

hint

When: (p.contentReadabilityHints.length > 0) AND (hint.includes('thin content'))

Deduct 5 points

Hreflang set is missing a self-referencing tag — reduces geo-targeting accuracy

When: (p.hasHreflang) AND (p.hreflangMissingSelfRef)

Deduct 5 points

Hreflang set is missing x-default fallback

When: (p.hasHreflang) AND (p.hreflangMissingXDefault)

Deduct 8 points

No hreflang tags — generative engines cannot determine language/region targeting

When: NOT (p.hasHreflang)

Deduct 4 points

No statistics or data points in substantial content

When: NOT (p.statisticCount >= 5) AND (p.statisticCount === 0 && p.wordCount > 500)

Deduct 3 points

Conditional deduction; see the exact trigger.

When: NOT (p.originalDataSignals >= 3) AND (p.originalDataSignals === 0)

Deduct 5 points

Content appears stale (over 1 year since last update)

When: NOT (p.contentFreshnessSignal === 'fresh') AND NOT (p.contentFreshnessSignal === 'recent') AND (p.contentFreshnessSignal === 'stale')

Deduct 3 points

Conditional deduction; see the exact trigger.

When: NOT (p.uniqueInsightPatterns >= 3)

Varies

Question-Answer Patterns

hasQAPattern and question-based H2/H3 headings with concise answers are the #1 content pattern cited in AI Overviews and Perplexity responses.

Varies

Data/Comparison Tables

tableCount measures structured tabular data. Generative AI frequently cites tables for comparison queries ("X vs Y") because they provide pre-structured, extractable information.

Varies

Content Depth (>1000 words)

wordCount over 1,000 with uniqueInsightPatterns makes pages 5× more likely to be cited by generative engines. thinContentSignal triggers at <300 words.

Varies

List-Based Content

listCount and orderedListCount detect the second most-extracted content format by generative engines after tables. Numbered steps and bullet points are AI's preferred citation structure.

Varies

Hreflang (with Self-Ref & x-default)

hasHreflang, hreflangValues, hreflangMissingSelfRef, and hreflangMissingXDefault are critical for international SEO. Missing self-referencing tags or x-default causes wrong-language content in localized AI results.

Varies

Statistics/Data Density

statisticCount measures specific numbers and percentages. Pages with concrete data points are treated as more authoritative by generative engines than opinion-based content.

Varies

Original Research Signals

originalDataSignals detect charts, figures, and data tables suggesting first-party research that generative AI models cite preferentially over derivative content.

Varies

Content Freshness

contentFreshnessSignal ("fresh"/"aging"/"stale") based on dateModified and datePublished. Content over 1 year old is progressively deprioritized by generative engines.

Varies

Unique Insight Patterns

uniqueInsightPatterns count phrases like "our research found," "we discovered," "based on our analysis" that signal first-hand expertise generative engines recognize.

Varies

RTL & i18n Support

hasRtlSupport (direction: rtl for Arabic/Hebrew), hasCurrencyFormatting, and i18nSignalCount measure internationalization depth beyond basic hreflang tags.

Varies

FAQ Count

faqCount directly measures the volume of question-answer pairs available for AI extraction. 5+ FAQs significantly increase citation probability.

Varies

Question-Phrased Sub-Headings · v5.0

On pages with 3+ sub-headings we measure the share phrased as natural-language questions (starting with what/how/why/when/where/who/which or ending in ?). Below 20%, generative engines struggle to extract and cite direct answers. Converting key sections into questions maps content to how users actually query AI.

Varies

Comparison Tables & Step-by-Step Blocks · v5.0

We look for comparison tables (or "vs"/"versus"/"compared to" language) and ordered step-by-step blocks (3+ ordered list items). These are the structured formats generative engines most readily lift into citable answers; their absence limits extractability.

−2 / 0

Citation placeholder links · v5.2

Content links must not contain unexpanded template placeholders. A failure deducts two points; pass, review and not applicable deduct none.

−2 / 0

Publication date order · v5.2

Article dates must parse and modification must not precede publication. A failure deducts two points; pass, review and not applicable deduct none.

Futuristic smartphone floating in space with holographic progressive web app interface expanding outward and responsive design grids
Futuristic smartphone floating in space with holographic progressive web app interface expanding outward and responsive design grids
19 factors evaluated
Current source-derived deductions — 19 conditional rules

The factors below explain grouped concepts, so their deductions vary. These current base-engine rules give the exact conditional amounts. Extension outcomes and coverage checks are documented in the PDF; content-substance caps also apply.

Deduct 8 points

Viewport does not include width=device-width

When: (p.hasViewport) AND (!p.viewportContent.includes('width=device-width'))

Deduct 25 points

Missing viewport meta tag — page will not render correctly on mobile

When: NOT (p.hasViewport)

Deduct 5 points

Missing or non-HTML5 doctype

When: NOT (p.doctype)

Deduct 5 points

Missing charset declaration

When: NOT (p.hasCharset)

Deduct 5 points

No theme-color meta tag

When: NOT (p.hasThemeColor)

Deduct 8 points

No web app manifest found

When: NOT (p.hasManifest)

Deduct 5 points

Missing Apple touch icon

When: NOT (p.hasTouchIcons)

Deduct 5 points

Conditional deduction; see the exact trigger.

When: NOT (p.hasServiceWorker)

Deduct 8 points

No responsive image srcset — mobile users may download oversized images

When: NOT (p.hasSrcset) AND (p.imageCount > 3)

Deduct 8 points

Viewport disables user zoom (maximum-scale=1 or user-scalable=no)

When: (p.viewportDisablesZoom)

Deduct 8 points

[observed value] potentially undersized touch targets detected

When: (p.smallTouchTargets > 10)

Deduct 4 points

[observed value] small touch target(s) may be difficult to tap on mobile

When: NOT (p.smallTouchTargets > 10) AND (p.smallTouchTargets > 3)

Deduct 8 points

Fixed-width elements detected (>800px) — may cause horizontal scrolling on mobile

When: (p.hasFixedWidthElements)

Deduct 5 points

Popup/modal/interstitial detected — Google penalizes intrusive interstitials on mobile

When: (p.hasPopupOrModal)

Deduct 3 points

Manifest present but no service worker — PWA install prompt will not fire

When: NOT (p.hasManifest && p.hasServiceWorker && p.isHttps) AND (p.hasManifest && !p.hasServiceWorker)

Deduct 3 points

Only [observed value] manifest icon size(s) — recommend at least 4 (192, 384, 512, maskable)

When: NOT (p.manifestIconsCount >= 4) AND (p.manifestIconsCount > 0 && p.manifestIconsCount < 4)

Deduct 2 points

Conditional deduction; see the exact trigger.

When: NOT (p.touchFeedbackDetected)

Deduct 5 points

Estimated page weight ~[observed value]KB — heavy for mobile data plans

When: (p.estimatedPageWeightKb > 0) AND (p.estimatedPageWeightKb > 5000)

Deduct 5 points

Estimated page weight ~[observed value]KB — heavy for mobile data plans

When: (p.estimatedPageWeightKb > 0) AND NOT (p.estimatedPageWeightKb > 5000) AND (p.estimatedPageWeightKb > 3000 && !p.isModernFramework)

Varies

Viewport Meta Tag

hasViewport is the most critical mobile signal. Without viewport meta, mobile browsers render at desktop width (typically 980px), making text unreadably small and buttons untappable.

Varies

Viewport Zoom Restriction

viewportDisablesZoom (maximum-scale=1, user-scalable=no) prevents users from zooming, violating WCAG 1.4.4. Google penalizes zoom-restricted viewports in mobile-first indexing.

Varies

Touch Target Size

smallTouchTargets counts interactive elements smaller than 44×44px (Apple HIG) / 48×48px (Material Design). Undersized targets cause accidental clicks and "fat finger" frustration.

Varies

Fixed-Width Elements

hasFixedWidthElements detects elements with fixed pixel widths over 800px that cause horizontal scrolling on mobile — a severe usability failure.

Varies

Web App Manifest

hasManifest enables PWA features: add-to-homescreen, custom theme colors, splash screens, and app-like display modes.

Varies

PWA Install Readiness

installPromptReady requires manifest + service worker + HTTPS for the browser's PWA install prompt to appear.

Varies

Manifest Icon Coverage

manifestIconsCount < 4 means distorted or missing icons across devices. Apple, Android, and Windows each need different icon sizes.

Varies

Service Worker

hasServiceWorker enables offline capability, background sync, push notifications, and aggressive caching strategies for near-instant return visits.

Varies

Responsive Images (srcset)

hasSrcset prevents mobile devices from downloading full-resolution desktop images, wasting 40–70% bandwidth on unnecessary pixels.

Varies

Popup/Interstitial Detection

hasPopupOrModal triggers Google's intrusive interstitial penalty when popups cover more than 50% of mobile viewport content.

Varies

Touch Feedback

touchFeedbackDetected (CSS :active states, tap-highlight) provides visual confirmation that a user's tap registered, reducing perceived latency.

Varies

Safe Area Insets

hasSafeAreaInsets (env(safe-area-inset-*)) ensures content avoids notches, rounded corners, and home indicators on modern smartphones.

Varies

Orientation Handling

hasOrientationHandling detects CSS @media (orientation: landscape) or orientation-lock meta tags for proper landscape/portrait adaptation.

Varies

Hamburger Menu Detection

hasHamburgerMenu confirms mobile navigation pattern implementation, though we don't penalize for alternative patterns like tab bars.

Varies

Page Weight (Sustainability)

estimatedPageWeightKb and sustainabilityScore evaluate total transfer size. Pages over 3MB are heavy for mobile data; under 1MB is lightweight. Lower page weight also reduces carbon footprint.

Varies

Apple Web-App Meta Tags · v5.0

We check apple-mobile-web-app-capable, -status-bar-style, and -title. Missing two or more of these produces a poor iOS home-screen install experience — wrong status-bar styling, generic title, and no standalone display. Complete tags deliver a polished app-like install on iPhone/iPad.

Varies

viewport-fit=cover for Notched Devices · v5.0

When the viewport meta lacks viewport-fit=cover, content cannot extend edge-to-edge on notched / Dynamic-Island devices and safe-area-inset padding has no effect. Adding it (with safe-area-inset padding) lets your layout render correctly around modern device cutouts.

Varies

Images Without Dimensions · v5.1

Numeric value for images without dimensions. [observed value] image(s) lack explicit width/height — a common cause of layout shift (CLS)

−2 / 0

Responsive sizes width descriptors · v5.2

Width-descriptor srcsets without sizes default to viewport width; verify download sizing. A failure deducts two points; pass, review and not applicable deduct none.

Futuristic voice assistant and answer engine interface with sound waves, featured snippet cards, and question symbols in dark space
Futuristic voice assistant and answer engine interface with sound waves, featured snippet cards, and question symbols in dark space
13 factors evaluated
Current source-derived deductions — 14 conditional rules

The factors below explain grouped concepts, so their deductions vary. These current base-engine rules give the exact conditional amounts. Extension outcomes and coverage checks are documented in the PDF; content-substance caps also apply.

Deduct 8 points

FAQ content exists but lacks FAQPage schema

When: NOT (p.hasFAQSchema) AND (p.faqCount > 0)

Deduct 15 points

No FAQ content or schema

When: NOT (p.hasFAQSchema) AND NOT (p.faqCount > 0)

Deduct 5 points

How-to content exists but lacks HowTo schema

When: NOT (p.hasHowToSchema) AND (p.hasHowToPattern)

Deduct 5 points

Conditional deduction; see the exact trigger.

When: NOT (p.hasHowToSchema) AND NOT (p.hasHowToPattern)

Deduct 10 points

Content not optimized for featured snippets

When: NOT (p.hasQAPattern)

Deduct 8 points

No Speakable schema for voice search

When: NOT (p.hasSpeakableSchema)

Deduct 5 points

Paragraphs too long for answer engine extraction

When: NOT (p.avgWordsPerParagraph > 0 && p.avgWordsPerParagraph <= 30) AND (p.avgWordsPerParagraph > 40)

Deduct 3 points

Conditional deduction; see the exact trigger.

When: NOT (p.hasBreadcrumbNav && p.hasBreadcrumbSchema) AND (p.hasBreadcrumbNav)

Deduct 5 points

No breadcrumb navigation

When: NOT (p.hasBreadcrumbNav && p.hasBreadcrumbSchema) AND NOT (p.hasBreadcrumbNav)

Deduct 5 points

Conditional deduction; see the exact trigger.

When: NOT (p.listCount >= 3)

Deduct 3 points

Conditional deduction; see the exact trigger.

When: NOT (p.hasVideoObject)

Deduct 4 points

Few concise answer paragraphs for snippet extraction

When: NOT (p.conciseAnswerBlocks >= 5) AND (p.conciseAnswerBlocks < 2)

Deduct 4 points

No direct answer patterns ("X is defined as...", "X refers to...")

When: NOT (p.directAnswerPatterns >= 3) AND (p.directAnswerPatterns === 0)

Deduct 3 points

Paragraphs too long for voice assistant extraction

When: NOT (p.voiceReadyContentLength) AND (p.avgWordsPerParagraph > 40)

Varies

FAQPage Schema

hasFAQSchema is the most direct path to expandable FAQ rich results in Google. Combined with faqCount, we measure both schema implementation and content availability.

Varies

Featured Snippet Readiness

Position-zero snippets capture ~35% of all clicks. conciseAnswerBlocks (40–60 word paragraphs after question headings) are the required format for snippet extraction.

Varies

Speakable Schema

hasSpeakableSchema identifies which content sections voice assistants (Google Assistant, Alexa, Siri) should read aloud in response to voice queries.

Varies

HowTo Schema & Patterns

hasHowToSchema enables rich step-by-step results. hasHowToPattern detects instructional content structure even without formal schema markup.

Varies

Concise Answer Blocks

conciseAnswerBlocks count paragraphs between 10–50 words that directly answer questions — the exact format targeted by Google's snippet extraction algorithm.

Varies

Direct Answer Patterns

directAnswerPatterns detect definitional statements ("X is defined as…", "X refers to…") that are the #1 pattern extracted for knowledge panel answers.

Varies

Breadcrumb Navigation & Schema

hasBreadcrumbSchema and hasBreadcrumbNav enable breadcrumb rich results showing site hierarchy in SERPs, improving click-through rates by 20–30%.

Varies

Voice-Ready Content Length

voiceReadyContentLength checks that paragraphs are under 30 words — the optimal length for voice assistant readback without losing listener attention.

Varies

Video Content & Schema

hasVideoObject schema enables video rich results that appear in ~25% of featured snippet positions, capturing visual-first searchers.

Varies

Definition Lists

definitionLists (<dl>/<dt>/<dd>) are semantic HTML elements specifically designed for term-definition pairs that answer engines can extract.

Varies

Q&A Pattern Coverage

hasQAPattern combined with faqCount measures the breadth of question-answer content. 5+ Q&A pairs significantly increase chances of appearing in People Also Ask boxes.

Varies

Concise Answer Under Question Heading · v5.0

We check whether a self-contained 40–60 word answer paragraph directly follows a question-phrased H2/H3. This exact format is what Google's snippet extraction and voice assistants lift verbatim. Leading each question section with a ~40–60 word answer is the single highest-leverage pattern for winning featured snippets and voice answers.

−2 / 0

Answer snippet exclusion · v5.2

Review snippet exclusions on marked-up answers; do not add answer markup to unrelated pages. A failure deducts two points; pass, review and not applicable deduct none.

Futuristic structured data visualization showing JSON-LD code blocks as 3D holographic cards with schema type connections as glowing lines
Futuristic structured data visualization showing JSON-LD code blocks as 3D holographic cards with schema type connections as glowing lines
13 factors evaluated
Current source-derived deductions — 0 conditional rules

The factors below explain grouped concepts, so their deductions vary. These current base-engine rules give the exact conditional amounts. Extension outcomes and coverage checks are documented in the PDF; content-substance caps also apply.

Varies

Schema Presence

Zero hasSchemaOrg is the single largest penalty. Without any structured data, search engines and AI have no machine-readable understanding of your content type, author, or organization.

Varies

Tier 1 Schema Types

missingHighImpactSchemas identifies absent Tier 1 types: Organization, WebSite, Article, Product, FAQPage, BreadcrumbList, LocalBusiness. schemaTier maps each detected type to its impact tier.

Varies

Tier 2 Schema Types

hasPersonSchema, hasHowToSchema, hasServiceSchema, hasEventSchema, hasReviewSchema extend rich result eligibility beyond core types.

Varies

Property Completeness

schemaPropertyCompleteness scores each schema type's property coverage (0–100%). An Organization with only a name is far less useful than one with address, phone, logo, sameAs, and foundingDate.

Varies

JSON-LD Format

jsonLdOnly is preferred by Google. hasMicrodataOrRdfa is legacy — JSON-LD is easier to maintain, doesn't interfere with HTML structure, and supports server-side rendering.

Varies

Schema Validity

schemaValidityHints detect JSON-LD parse errors, missing required fields, and type mismatches. Invalid schema is silently ignored by search engines. hasDeprecatedSchemaProperties flags obsolete properties.

Varies

sameAs Entity Linking

hasSameAs and sameAsLinks count connections to Wikipedia, Wikidata, LinkedIn, and social profiles that help search engines disambiguate your brand entity in the Knowledge Graph.

Varies

SearchAction Schema

Google retired the sitelinks search box in November 2024. This markup does not unlock that feature and its absence receives no penalty.

Varies

Action Schemas (Buy/Subscribe)

hasBuyAction and hasSubscribeAction signal conversion intent, potentially enabling direct purchase/subscribe rich results in AI-powered commerce.

Varies

Rich Results Eligibility

richResultsEligible and additionalRichResults enumerate which rich results your schema qualifies for: FAQ dropdowns, star ratings, how-to steps, product cards, event listings.

Varies

Nested Schema Depth

nestedSchemaDepth and schemaDepth measure nesting sophistication. Deeper nesting (author within Article, offers within Product, review within LocalBusiness) enables richer Knowledge Graph connections.

Varies

Schema Type Count & Diversity

schemaCount and schemaTypes diversity measure implementation breadth. More distinct, valid types provide richer machine-readable context.

Varies

Page-Type-Aware Schema Maximization · v5.0

A new engine detects the dominant page type from content signals and recommends the maximal schema plus the high-value properties not yet present: FAQPage when 3+ Q&A blocks exist, HowTo for step-by-step content, Article/BlogPosting (with author, datePublished, dateModified, image, publisher) for long-form pages, Product (with offers, aggregateRating, review) for commerce pages, and LocalBusiness (with address, geo, openingHoursSpecification, telephone) for local pages. A connected @graph of 4+ types is rewarded as structured-data maturity.

Futuristic local map interface with holographic building pins, star ratings floating above locations, and location data streams
Futuristic local map interface with holographic building pins, star ratings floating above locations, and location data streams
13 factors evaluated
Current source-derived deductions — 0 conditional rules

The factors below explain grouped concepts, so their deductions vary. These current base-engine rules give the exact conditional amounts. Extension outcomes and coverage checks are documented in the PDF; content-substance caps also apply.

Varies

NAP (Name, Address, Phone)

hasNAP and napDetails consistency is the #1 local ranking factor. NAP must match your Google Business Profile exactly across all web presences.

Varies

LocalBusiness Schema

hasLocalBusinessSchema and localBusinessTypes provide Google with structured business data: name, address, phone, hours, geo coordinates, price range, and payment methods.

Varies

Phone Number

phoneNumbers with clickable tel: links are essential for mobile users and signal local business legitimacy. Multiple numbers may indicate multi-location businesses.

Varies

Google Maps Embed

hasGoogleMapsEmbed provides visual location confirmation and helps Google associate your site with a specific geographic point for local pack ranking.

Varies

Address Microdata

hasAddressMicrodata (PostalAddress schema) makes your address machine-readable for accurate parsing by search engines and mapping services.

Varies

Geo Meta Tags

hasGeoMeta (geo.region, geo.placename, geo.position) meta tags explicitly declare your geographic targeting for regional search results.

Varies

Opening Hours

hasOpeningHours is a top local ranking factor. Business hours appear prominently in local pack results and Google Knowledge Panels.

Varies

Review/Rating Schema

reviewCountFromSchema and averageRating display star ratings in SERPs. Reviews are the #2 local ranking factor after NAP consistency.

Varies

Service Area Schema

hasServiceAreaSchema defines your service radius beyond your physical address, critical for service-area businesses (plumbers, electricians, delivery).

Varies

Multiple Locations

hasMultipleLocations detects multi-location business patterns that may need separate location pages for optimal local pack coverage.

Varies

Email & Contact Methods

emailAddresses and additional contact methods (contact forms, chat widgets) provide alternative communication channels that improve local engagement signals.

Varies

City/Region in Title, H1 & Intro · v5.0

When local-business signals (tel: link or a street address) are present but no explicit "City, State" appears in the title, H1, or opening paragraph, we flag it. Placing your city/region in these prominent locations reinforces local relevance for "near me" and geo-modified queries.

Varies

NAP Phone Consistency · v5.0

We compare the visible phone number against the schema telephone property. A mismatch (after normalization) directly undermines local ranking, which depends on identical Name/Address/Phone across visible content, structured data, and directories. If a phone is shown but absent from schema, we recommend adding telephone so NAP is machine-verifiable.

WCAG 2.2 deep compliance visualization — violet holographic accessibility hub with universal access symbol, contrast dials, keyboard focus rings, and motion-sensitivity waveforms for web content accessibility guidelines conformance
WCAG 2.2 deep compliance visualization — violet holographic accessibility hub with universal access symbol, contrast dials, keyboard focus rings, and motion-sensitivity waveforms for web content accessibility guidelines conformance
17 factors evaluated
Current source-derived deductions — 22 conditional rules

The factors below explain grouped concepts, so their deductions vary. These current base-engine rules give the exact conditional amounts. Extension outcomes and coverage checks are documented in the PDF; content-substance caps also apply.

Deduct 10 points

No prefers-reduced-motion support

When: NOT (p.hasReducedMotion)

Deduct 8 points

No high contrast mode support

When: NOT (p.hasHighContrastMode)

Deduct 8 points

Links may not be distinguishable from surrounding text

When: NOT (p.linkDistinguishable)

Deduct 5 points

No error suggestion mechanisms detected in forms

When: NOT (p.hasErrorSuggestions) AND (p.formCount > 0)

Deduct 10 points

[observed value] autoplay media element(s) detected

When: (p.autoplayMedia > 0)

Deduct 8 points

No relative units for text sizing detected

When: NOT (p.hasTextResize)

Deduct 5 points

Low semantic-to-div ratio — [observed value] divs vs [observed value] semantic elements

When: NOT (wcagSemanticRatio > 8) AND (wcagSemCount > 0)

Deduct 10 points

No semantic HTML5 elements detected

When: NOT (wcagSemanticRatio > 8) AND NOT (wcagSemCount > 0)

Deduct 5 points

[observed value] elements with tabindex="-1" — may hide content from keyboard users

When: (p.negativeTabindex > 5)

Deduct deduct points

[observed value] potential color contrast issue(s)

When: (p.contrastIssueCount > 0)

Deduct 8 points

No focus styles detected

When: NOT (p.hasFocusStyles)

Deduct 5 points

Missing lang attribute

When: NOT (p.hasLangAttr)

Deduct Math.min(8, p.ariaRoleValidity.length * 2) points

Invalid ARIA roles: [observed value]

When: (p.ariaRoleValidity.length > 0)

Deduct 5 points

High cognitive load signals (auto-carousels, animations, notification badges, complex layouts)

When: (p.cognitiveLoadScore > 15)

Deduct 2 points

Moderate cognitive load from interactive patterns

When: NOT (p.cognitiveLoadScore > 15) AND (p.cognitiveLoadScore > 8 && !p.isModernFramework)

Deduct 4 points

[observed value] heading level skip(s) — confuses screen reader navigation

When: (p.headingLevelSkips > 2)

Deduct 5 points

No form error identification detected

When: NOT (p.formErrorIdentification) AND (p.formCount > 0)

Deduct 3 points

Timed elements detected without option to extend

When: (!p.timingAdjustable)

Deduct 5 points

Multiple fixed/sticky elements may obscure focused content (WCAG 2.4.11)

When: (!p.focusNotObscured)

Deduct 5 points

Authentication form may require cognitive tasks without alternatives (WCAG 3.3.8)

When: (!p.accessibleAuth && p.formCount > 0)

Deduct 5 points

Drag-and-drop detected without pointer-based alternative (WCAG 2.5.7)

When: (!p.draggingAlternative)

Deduct 3 points

Conditional deduction; see the exact trigger.

When: NOT (p.ariaLiveRegionCount >= 2) AND (p.ariaLiveRegionCount === 0 && p.formCount > 0)

Varies

Reduced Motion Support

hasReducedMotion checks for @media (prefers-reduced-motion). reducedMotionEnforced verifies that animations are actually disabled, not just detected. Users with vestibular disorders experience nausea from animations (WCAG 2.3.3).

Varies

High Contrast Mode

hasHighContrastMode checks for @media (forced-colors) / @media (-ms-high-contrast) support. Users with low vision depend on forced-colors mode to make content readable.

Varies

Link Distinguishability

linkDistinguishable verifies links are identifiable by more than just color (WCAG 1.4.1). Underline, font-weight, or border-bottom must supplement color changes.

Varies

Text Resize (rem/em)

hasTextResize checks for relative font units. Pixel font sizes don't scale when users increase browser zoom to 200% (WCAG 1.4.4 requirement).

Varies

Focus Not Obscured (WCAG 2.4.11)

focusNotObscured is a WCAG 2.2 criterion. Sticky headers, floating CTAs, and cookie banners can cover the focus indicator, making keyboard navigation impossible.

Varies

Accessible Authentication (WCAG 3.3.8)

accessibleAuth checks that login forms support autocomplete attributes and password managers. Authentication must not demand cognitive function tests (WCAG 2.2).

Varies

Dragging Alternatives (WCAG 2.5.7)

draggingAlternative verifies that drag-and-drop interactions have click/tap alternatives. Users with motor impairments cannot perform dragging motions (WCAG 2.2).

Varies

ARIA Live Regions

ariaLiveRegionCount measures dynamic content announcements. Toast notifications, form validation messages, and chat updates are invisible to screen readers without aria-live="polite" or "assertive".

Varies

Color Contrast Issues

contrastIssueCount from colorContrastHints measures WCAG 1.4.3 violations. Poor contrast affects 300 million color-blind users and 2.2 billion people with vision impairment worldwide.

Varies

Cognitive Load Score

cognitiveLoadScore evaluates auto-playing carousels, excessive animations, information density, and simultaneous dynamic updates that increase cognitive burden for users with ADHD, autism, and cognitive disabilities.

Varies

Heading Level Skips

headingLevelSkips (e.g., H2 → H4 skipping H3) breaks screen reader navigation and content hierarchy understanding.

Varies

ARIA Role Validity

ariaRoleValidity audits all ARIA roles for correctness. Invalid roles (role="modal" instead of role="dialog") are ignored by assistive technology, breaking custom widget accessibility.

Varies

Autoplay Media

autoplayMedia violates WCAG 1.4.2. Auto-playing audio/video is disorienting for cognitive disabilities and interrupts screen reader output. timeBasedMedia counts all time-based media elements.

Varies

Timing Adjustable

timingAdjustable verifies that session timeouts and auto-advancing content can be extended or paused (WCAG 2.2.1). Users with motor or cognitive disabilities need more time.

Varies

Form Error Identification

formErrorIdentification and hasErrorSuggestions check that form validation errors are clearly described and associated with the correct field (WCAG 3.3.1, 3.3.3).

Varies

Content on Hover/Focus (WCAG 2.2 1.4.13) · v5.0

We count interactive elements (links, buttons, role="button") relying on native title tooltips. When 3+ do, we flag it: native title tooltips are not dismissable, hoverable, or persistent, failing WCAG 2.2 Success Criterion 1.4.13. Replace them with accessible tooltip components that meet all three requirements.

−2 / 0

Aria describedby targets · v5.2

Every aria-describedby reference must resolve to an existing element. A failure deducts two points; pass, review and not applicable deduct none.

Futuristic mathematical algorithm visualization showing the composite scoring formula with glowing equations, weight percentages as floating orbs, and letter grade scale

Composite Scoring Algorithm

Each dimension starts at 100, loses points for applicable failing factors, and clamps to [0, 100]. A content-substance cap is applied before the weighted average. The caps range from 12–100 for content dimensions, 30–100 for accessibility/WCAG/mobile, 45–100 for performance and 55–100 for security, depending on available substance.

// Each dimension: start at 100, subtract per-factor deductions, clamp to [0, 100]
dimensionScore = clamp(100 - sumOfDeductions, 0, 100)
// Composite Score — weighted average (weights sum to 1.00)
compositeScore = round(
SEO × 0.15 +
Performance × 0.14 +
Security × 0.10 +
AI_Readiness × 0.10 +
AIO × 0.09 +
Accessibility × 0.08 +
GEO × 0.08 +
Mobile × 0.08 +
AEO × 0.06 +
Schema.org × 0.06 +
Local_SEO × 0.04 +
WCAG × 0.02
)
// Final composite clamped to [0, 100]
finalScore = clamp(compositeScore, 0, 100)

Letter Grade Scale

A+
97–100
A
93–96
A−
90–92
B+
87–89
B
83–86
B−
80–82
C+
77–79
C
73–76
C−
70–72
D+
67–69
D
63–66
D−
60–62
F
0–59

Impact / Effort Ratings

Every recommendation in the audit report includes an Impact/Effort rating to help you prioritize fixes:

Impact: High
Fixing this will produce a large, measurable improvement in score, rankings, or user experience
Impact: Medium
Noticeable improvement; recommended but not urgent
Impact: Low
Minor improvement; address when convenient
Effort: High
Requires significant development time, architecture changes, or specialist skills
Effort: Medium
A few hours of work for a competent developer
Effort: Low
Quick fix — often a single line of HTML or a config change

Best Strategy: Start with High Impact / Low Effort fixes first (title tags, meta descriptions, missing headers). These deliver the biggest score improvements for the least work.

Methodology Note

All scores are computed deterministically from HTML source code, HTTP response headers, and robots.txt content. No external APIs, no AI inference, and no Lighthouse simulations are used. Core Web Vitals metrics (LCP, CLS, INP) are proxy estimates based on HTML structure analysis — for lab measurements, use Google PageSpeed Insights or Chrome DevTools.

© 2026 Digital Marketing Company · DigitalMarketingCo.org · Scoring Guide v5.2