Every page must pass these checks before going live. The system enforces them automatically at three points:
Translation costs $0.02–0.50 per page. The Diamond Standard is the gate that prevents thin content from wasting budget.
| Field | Rule |
|---|---|
title | Non-empty |
description | Non-empty, 120-160 chars |
focusKeyword | Non-empty, unique across site |
date | ISO format |
Posts also require: category, permalink.
Provider pages also require: template: provider, parent: vpn.
Scored out of 85. Measures structural richness beyond plain text.
| Signal | Points |
|---|---|
FAQ section (## FAQ heading) | 10 |
| Table (markdown or HTML) | 10 |
| List (bullets or numbered) | 10 |
| Image | 10 |
| Blockquote | 5 |
| Word count 1,000+ | 15 |
| 3+ internal links to VPN.com pages | 15 |
| 1+ external authority link | 10 |
| Score | Tier | Meaning |
|---|---|---|
| 60-85 | Diamond | Publish-ready. Worth translating. |
| 40-59 | Silver | Acceptable. Has specific gaps. |
| 0-39 | Thin | Flagged. Will waste translation budget. |
Fixing a Thin page:
## Frequently Asked QuestionsOne keyword per page, unique across the site. Blocks on collision.
CI checks after build:
<title>, <h1>, meta description, first 100 words, one <h2>Cannibalization: Two pages targeting the same intent splits authority — both lose. Either merge the pages or differentiate keywords.
| Type | Minimum | Target |
|---|---|---|
| Blog post | 300 words | 1,000+ |
| Provider review | 300 words | 2,000+ |
| Pillar page | 300 words | 1,000+ |
| Legal page | None | Complete and dated |
A 300-word provider review will publish but gets flagged as Thin and excluded from translation.
Set translate: true in frontmatter (or check "Include in translation" in the editor). Pages with translate: true and enrichment score under 40 are flagged as translation budget risk.
translate: true, all language versions commit atomically. Live in ~2 minutes.updated frontmatter field on meaningful revisionsBuild auto-generates JSON-LD — no manual schema needed if frontmatter is complete.
| Page type | Schema generated |
|---|---|
| Blog post | Article (author, date) |
| Provider review | SoftwareApplication + Review (with rating) |
| Landing page | WebSite + SearchAction |
| All pages | Organization, BreadcrumbList |
[ ] Title: 40-60 chars, contains focus keyword
[ ] Description: 120-160 chars
[ ] Focus keyword: unique, specific, in title
[ ] Date present
[ ] Word count: 300+ minimum, 1,000+ recommended
[ ] At least 1 table or comparison
[ ] At least 1 list
[ ] 3+ internal links
[ ] 1+ external link
[ ] Updated within 6 months
| File | Purpose |
|---|---|
scripts/seo-audit.mjs | 16 post-build HTML checks |
scripts/enrichment-check.mjs | Enrichment scorer (Diamond/Silver/Thin) |
src/content.config.ts | Zod schemas — build fails on missing fields |
vpn-editor/static/index.html | Editor SPA — Diamond Standard modal |
scripts/build.sh | Local build pipeline |