Production-grade SEO auditing engine for Next.js applications.
Crawls a domain, runs 40+ checks across 11 categories, and returns a fully typed, prioritised SEOReport.
sequenceDiagram
participant Caller
participant scanDomain
participant fetchUrl
participant analysePage
participant runDomainChecks
Caller->>scanDomain: domain + ScanOptions
scanDomain->>scanDomain: Normalise seed URL, init BFS queue
loop BFS — up to maxPages
scanDomain->>fetchUrl: GET page
fetchUrl-->>scanDomain: html, headers, finalUrl
scanDomain->>analysePage: html + response headers
analysePage-->>scanDomain: CheckResult[], outboundLinks[]
scanDomain->>scanDomain: Enqueue new same-origin links
end
scanDomain->>runDomainChecks: origin
runDomainChecks->>fetchUrl: /robots.txt, /sitemap.xml, / (security headers)
runDomainChecks-->>scanDomain: domain CheckResult[]
scanDomain->>scanDomain: Aggregate → score → sort → top priorities
scanDomain-->>Caller: SEOReport
| Category | Checks |
|---|---|
| 📋 meta | Title Tag · Meta Description · Canonical URL · Meta Robots · URL Structure · Keyword in URL · hreflang |
| 📝 content | H1 Heading · Heading Hierarchy · Word Count · Keyword in Intro · Readability |
| ⚙️ technical | Doctype · Charset · Viewport · Compression · Caching · Page Size · Favicon |
| ⚡ performance | Lazy Loading · Render Blocking · Resource Hints |
| 📣 social | Open Graph · Twitter Cards |
| ♿ accessibility | HTML lang · Skip Navigation · Semantic Landmarks · Form Labels · ARIA Usage |
| 🔒 security | HTTPS · HSTS · Security Headers |
| 🔗 links | Internal Links · Anchor Text Quality · External rel Security · Placeholder Links |
| 🖼️ images | Alt Text · Image Dimensions |
| 🧩 structured-data | JSON-LD Validity · Breadcrumb Schema · FAQ Schema · Video Schema |
| 🌐 domain | Robots.txt · XML Sitemap |
classDiagram
class SEOReport {
+string domain
+ScanSummary summary
+number pagesScanned
+PageAnalysis[] pageAnalysis
+AggregatedCheck[] aggregatedChecks
+Record~CheckCategory, AggregatedCheck[]~ checksByCategory
+string scannedAt
+number durationMs
}
class ScanSummary {
+number score
+"A"|"B"|"C"|"D"|"F" grade
+number criticalIssues
+number warningIssues
+number passedChecks
+AggregatedCheck[] topPriorities
}
class PageAnalysis {
+string url
+string path
+number score
+number issuesCount
+CheckResult[] checks
}
class AggregatedCheck {
+string id
+CheckStatus status
+string currentValue
+number issueCount
+string worstPage
+PageBreakdown[] pageBreakdown
}
class CheckResult {
+string id
+CheckCategory category
+CheckStatus status
+string value
+string message
+string whyItMatters
+string howToFix
+string snippet
+string wcag
+"low"|"medium"|"high" effort
+"low"|"medium"|"high" impact
}
SEOReport --> ScanSummary
SEOReport --> PageAnalysis
SEOReport --> AggregatedCheck
PageAnalysis --> CheckResult
ScanSummary --> AggregatedCheck : topPriorities
Each page starts at 100 points. Checks deduct based on severity. Domain-level checks apply the same penalties to the final averaged score.
| Status | Delta |
|---|---|
🔴 critical |
−15 pts |
🟡 warning |
−5 pts |
🟢 good |
0 pts |
flowchart LR
A[100 pts] -->|each critical| B[-15]
A -->|each warning| C[-5]
B & C --> D[Page Score\nclamped 0–100]
D --> E[Avg across pages]
E -->|domain check penalties| F[Final Score]
F --> G{Grade}
G -->|≥90| A1[A]
G -->|≥75| B1[B]
G -->|≥60| C1[C]
G -->|≥45| D1[D]
G -->|<45| F1[F]
The crawler runs a BFS loop capped at maxPages. It automatically skips non-canonical paths to avoid wasting crawl budget:
| Skipped | Examples |
|---|---|
| Static assets | .js .css .png .woff2 |
| Framework internals | /_next/ /wp-admin/ /api/ |
| Feeds & archives | /feed/ /rss/ /2024/01/15/ |
| Search & filter URLs | ?s= ?filter= ?sort= |
| Transactional paths | /checkout/ /account/ /login/ |
Tracking parameters (
utm_*,fbclid,gclid, etc.) are stripped before deduplication. Redirect chains are fully resolved — both the original and final URLs are marked visited to prevent loops.
| Category | Check | 🔴 Critical | 🟡 Warning |
|---|---|---|---|
meta |
Title | Missing | < 30 or > 65 chars |
meta |
Meta Description | Missing | < 70 or > 160 chars |
meta |
Meta Robots | noindex detected |
nofollow detected |
meta |
Canonical | — | Missing or cross-page |
content |
H1 | Missing | Multiple H1s or > 70 chars |
content |
Word Count | < 100 words | < 300 words |
technical |
Viewport | Missing | user-scalable=no or no width=device-width |
technical |
Page Size | > 500 KB | > 150 KB |
security |
SSL | HTTP origin | — |
domain |
Robots.txt | Disallow: / traps all crawlers |
Missing or no Sitemap: ref |
images |
Alt Text | > 3 images missing alt |
Any image missing alt |