SEO Validation & Scoring
Catch missing tags at build time. Score each page out of 100 so you know exactly what to fix before going live.
validateSEO — Find Missing Tags
Pass an array of routes with their SEO configs. The library checks each page for missing or invalid fields and returns structured issues.
| Page | Field | Message | Severity |
|---|---|---|---|
| HomePage | canonical | Missing canonical URL | ⚠️ warning |
| HomePage | structured-data | No structured data (JSON-LD) | ⚠️ warning |
| TicketListPage | og:image | Missing og:image | ⚠️ warning |
| TicketListPage | structured-data | No structured data (JSON-LD) | ⚠️ warning |
HomePage: ⚠️ [canonical] Missing canonical URL ⚠️ [structured-data] No structured data (JSON-LD) TicketListPage: ⚠️ [og:image] Missing og:image ⚠️ [structured-data] No structured data (JSON-LD)
import {
validateSEO,
printValidationReport,
} from "react-ssr-seo-toolkit/validation";
import { appRoutes } from "./routes";
const issues = validateSEO(appRoutes);
if (issues.some((i) => i.severity === "error")) {
console.error(printValidationReport(issues));
process.exit(1); // fail the build
} else if (issues.length > 0) {
console.warn(printValidationReport(issues));
}getSEOScore — 100-Point Audit per Page
Scores a single page's SEO config across 10 checks. Useful for identifying the highest-impact missing fields.
✅ Well-configured page
🟢 TicketDetailPage
95/100❌ Sparse page (needs work)
🔴 TicketListPage
45/100🟢 SEO Score: TicketDetailPage 95/100 (95%) ✅ Title ✅ Description ✅ Canonical URL ✅ og:image ✅ og:title ✅ og:description ✅ Twitter Card ✅ Structured Data ✅ Robots Directives ❌ Hreflang (-5) — No hreflang alternates
import {
getSEOScore,
formatSEOScore,
} from "react-ssr-seo-toolkit/validation";
const result = getSEOScore(seoConfig, "TicketDetailPage");
console.log(formatSEOScore(result));
// 🟢 SEO Score: TicketDetailPage 75/100 (75%)
// ✅ Title
// ✅ Description
// ✅ Canonical URL
// ✅ og:image
// ✅ og:title
// ✅ og:description
// ✅ Twitter Card
// ✅ Structured Data
// ❌ Robots Directives (-5) — No robots directives
// ❌ Hreflang (-5) — No hreflang alternatesScoring Breakdown (100 points)
| Check | Points | Notes |
|---|---|---|
| Title | 20 | Full points if ≤60 chars, 10 if longer |
| Description | 15 | Full points if ≤160 chars, 8 if longer |
| Canonical URL | 10 | Must be set |
| og:image | 15 | At least one image in openGraph.images |
| og:title | 5 | openGraph.title or title fallback |
| og:description | 5 | openGraph.description or description fallback |
| Twitter Card | 10 | twitter.card must be set |
| Structured Data | 10 | jsonLd must be set |
| Robots Directives | 5 | robots config must be set |
| Hreflang | 5 | alternates array must have entries |
Features Demonstrated
Build-time Validation
Run validateSEO(routes) in your build script. Fail the build on errors, warn on missing optional fields.
Per-page Scoring
getSEOScore(config, name) audits any SEO config against 10 weighted checks and returns a 0–100 score.
Readable Reports
printValidationReport() and formatSEOScore() format results for terminal output with icons and color hints.
Typed Results
SEOValidationIssue[] and SEOScoreResult are fully typed — integrate with your CI pipeline or CMS.
Add validateSEO(routes) to your pre-build script and pipe the output to your CI logs. Pages with error severity should block deploys — pages with warning severity can be treated as tech debt.