Scoring Methodology
We never hide the formula. Every one of the 100 points is assigned to a specific, automatable test with a fixed scoring rule and raw evidence behind it — no black box. Score version v1.1.
Technical SEO & Crawlability
25 points| Test | Points | Scoring rule |
|---|---|---|
| Domain resolves | 2 | All required DNS lookups work = 2; intermittent/partial = 1; failure = 0 |
| Homepage response | 3 | 2xx = 3; valid 3xx destination = 2; 401/403/429 = 1; 4xx/5xx = 0 |
| Redirect quality | 1 | 0-1 hops = 1; 2-3 = 0.5; loop or 4+ = 0 |
| robots.txt reachable and valid | 1 | Valid = 1; missing = 0.5; malformed/server error = 0 |
| Site not blocked globally | 2 | Important crawlers allowed = 2; partial block = 1; Disallow: / = 0 |
| No accidental sitewide noindex | 3 | No sitewide noindex = 3; isolated pages = 1-2; homepage/sitewide = 0 |
| XML sitemap exists and parses | 2 | Valid = 2; discoverable but errors = 1; missing = 0 |
| Sitemap URL health | 2 | ≥95% healthy = 2; 80-94% = 1; below 80% = 0 |
| Canonical tags | 2 | ≥95% valid = 2; 80-94% = 1; below 80% = 0 |
| Internal broken-link rate | 3 | 0% = 3; ≤2.5% = 2; ≤5% = 1; above 5% = 0 (sampled up to 40 internal links) |
| JSON-LD parsing | 1 | All blocks parse = 1; some invalid = 0.5; all invalid = 0 |
| Nameserver redundancy | 0.5 | Two or more authoritative nameservers = 0.5 |
| SPF validity | 1 | One valid SPF record and ≤10 DNS lookups = 1; warning = 0.5; invalid = 0 |
| DMARC policy | 1 | p=reject = 1; quarantine = 0.75; none = 0.25; absent/invalid = 0 |
| CAA record | 0.5 | Valid CAA = 0.5; absent = 0 |
Performance & Mobile UX
20 points| Test | Points | Scoring rule |
|---|---|---|
| Lighthouse mobile performance | 8 | Lighthouse score × 8 ÷ 100 |
| Largest Contentful Paint (LCP) | 4 | ≤2.5s = 4; 2.5-4s = 2; above 4s = 0 |
| Cumulative Layout Shift (CLS) | 2 | ≤0.10 = 2; 0.10-0.25 = 1; above 0.25 = 0 |
| Total Blocking Time (TBT) | 2 | ≤200ms = 2; 200-600ms = 1; above 600ms = 0 |
| Transfer size | 1 | ≤1.5MB = 1; ≤3MB = 0.5; above 3MB = 0 |
| Request count | 1 | ≤60 = 1; ≤100 = 0.5; above 100 = 0 |
| Mobile viewport | 2 | Correct viewport = 2; incomplete = 1; missing = 0 |
Lighthouse runs three times on the same mobile profile; the median run is used.
On-Page Content & Structure
20 points| Test | Points | Scoring rule |
|---|---|---|
| Page titles | 3 | Presence 1 + suitable length 1 + uniqueness 1 |
| Meta descriptions | 2 | Presence 1 + uniqueness/suitable length 1 |
| Heading hierarchy | 3 | One descriptive H1 = 1.5; no skipped levels = 1; headings non-empty = 0.5 |
| Content sufficiency | 3 | Homepage/service-page thresholds based on page type |
| Image alt coverage | 2 | ≥95% = 2; 80-94% = 1; below 80% = 0 |
| Internal linking | 2 | Contextual links and no orphaned sampled pages = 2 |
| About/Contact trust pages | 2 | Both = 2; one = 1; neither = 0 |
| Duplicate-content similarity | 3 | No high-similarity pairs = 3; limited duplication = 1-2; widespread = 0 |
Duplicate-content check: 5-word shingles + Jaccard similarity. Below 70% = unique, 70-84% = possible duplication, 85%+ = probable duplicate, under 100 useful words = insufficient evidence.
Accessibility & Usability
10 points| Test | Points | Scoring rule |
|---|---|---|
| axe-core audit | 6 | Any critical issue = 0; otherwise deduct 1.0/serious, 0.35/moderate, 0.1/minor from a 6-point ceiling |
| Second-engine cross-check (pa11y) | 4 | Scored on issues pa11y confirms that axe-core did not already flag on the same element — not simply added twice |
Automated accessibility testing does not constitute a complete WCAG or legal-compliance audit.
Security & Trust
10 points| Test | Points | Scoring rule |
|---|---|---|
| HTTP → HTTPS redirect | 1 | Every tested HTTP entry redirects safely to HTTPS |
| Certificate validity | 1.5 | Trusted, correct hostname, unexpired and complete chain |
| Mixed content | 1 | No active/passive HTTP resources on HTTPS pages |
| Security-header presence | 1.5 | Proportional score across required headers |
| Insecure form actions | 0.5 | No form submits to HTTP |
| Sensitive exposure checks | 1 | No confirmed directory listing or exposed sensitive file |
| SSLyze TLS configuration | 2 | No legacy TLS, weak settings or known TLS vulnerability |
| Header/cookie/SRI quality | 1.5 | CSP 0.40 + HSTS 0.30 + cookie flags 0.30 + Referrer-Policy 0.20 + SRI 0.20 |
SSLyze checks run in an isolated, rate-limited worker. Exposure checks record only HTTP status and a safe fingerprint — the contents of .env/.git files are never downloaded or displayed.
AI Discovery Readiness — separate 100-point badge
Informational only. This badge does not affect the main Website Score.
Blocking an AI crawler may be an intentional business decision — it's labeled Restricted, not automatically scored as an error.
Overall formula
Overall Score = Technical + Performance + On-page + Authority + Accessibility + Security, where each category score (0-100) is weighted by its point share above. Category scores are never rounded before the final sum — only the displayed overall score is rounded.
| Score | Grade |
|---|---|
| 90-100 | A |
| 80-89 | B |
| 70-79 | C |
| 60-69 | D |
| Below 60 | F |
Critical-failure caps
Applied after the normal score is calculated — the lowest applicable cap wins. A temporary 429, bot challenge, DNS timeout, or scanner failure never triggers a cap; only a confirmed failure does.
| Critical failure | Overall cap |
|---|---|
| Domain does not resolve | 5 |
| Homepage consistently returns 5xx | 20 |
| Homepage/sitewide noindex | 35 |
| Invalid/expired/hostname-mismatched TLS | 40 |
| robots.txt blocks the entire site | 45 |
| Confirmed redirect loop | 30 |
Open-source tool stack
Playwright + Chromium (rendering), Lighthouse (performance), Cheerio (HTML parsing), axe-core + pa11y (two independent accessibility engines), SSLyze (TLS analysis), dnspython-equivalent DNS/SPF/DMARC checks, Common Crawl's public index, word-shingle + Jaccard similarity (duplicate content), BullMQ + Redis (job queue), and PostgreSQL (storage).
The most important protection: SSRF prevention
Every hostname is resolved and re-validated before each request and each redirect hop; private/reserved/metadata IP ranges are rejected; ports are restricted to 80/443; response sizes and scan time are capped; and Chromium/SSLyze workers run isolated from the rest of the platform. This is enforced on every scan, not just this report.