Files
ResumeSite/docs/spec/SEO_SPEC.md
T
2026-07-03 21:07:25 +02:00

46 lines
3.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SEO_SPEC.md
## 1. Goals & reality check
Primary discovery is *direct* (links from applications/LinkedIn/CV), not organic search. SEO effort therefore targets: (1) branded queries ("Connor Babbington developer") ranking the new site #1 in both languages, (2) clean link-preview cards everywhere recruiters paste URLs (Slack/Teams/LinkedIn/ATS), (3) not losing the existing domain's standing during the WordPress → new-site cutover.
## 2. Per-page metadata (both locales)
- **Titles** (patterns fixed in CONTENT_STRATEGY §7): home `Connor Babbington — Systems Developer (.NET, React) · Tønsberg, Norway` / `… Systemutvikler … · Tønsberg`; inner pages `<Page> · Connor Babbington`. ≤ 60 chars target.
- **Descriptions:** handwritten per page per locale, ≤ 155 chars, answer who/what/where. Stored in page-meta content (DATA_MODEL §6), length CI-checked.
- **Canonical:** self-referencing per locale page. **hreflang:** `en`, `nb`, `x-default → en` emitted from the slug map on every page — the twin-URL contract guarantees correctness; CI tests hreflang reciprocity.
- **robots:** index,follow everywhere except 404/colophon-draft states; `robots.txt` allows all + sitemap pointer.
## 3. Structured data (JSON-LD, build-time)
| Page | Schema |
|---|---|
| Home (both locales) | `Person`: name, jobTitle "Systems Developer"/"Systemutvikler", address (locality Tønsberg, country NO), email, sameAs [LinkedIn, git.cesnimda.uk], knowsLanguage [en, nb], knowsAbout [C#, .NET, React, Docker, …] |
| Case studies | `CreativeWork` (subtype `SoftwareApplication` where honest — JobTrack yes, InboxIntel as `SoftwareSourceCode`): name, description, author → Person, programmingLanguage, dateModified |
| CV hub | `Person` + `subjectOf` links to CV files |
| All | `WebSite` + `BreadcrumbList` on nested pages |
Builders are typed utilities with unit tests (TECH_SPEC §9.2) — malformed JSON-LD is worse than none.
## 4. OpenGraph / link previews
- Per-page, per-locale OG: `og:locale` (`en_GB`/`nb_NO`) + `og:locale:alternate`, title/description mirroring meta, `og:type` profile (home) / article (case studies).
- **OG images pre-generated at build** (one template per page kind, design-system styled: dark surface, name/page title, role line, trace motif, monogram; case studies add project name + stack line). 1200×630 PNG, per locale. Twitter/X summary_large_image tags mirrored.
- This directly fixes the current site's empty `og:title` embarrassment noted in Phase 1 research.
## 5. Sitemaps
- Build-generated sitemap index → one sitemap per locale; entries carry `xhtml:link` alternates (belt-and-braces with hreflang tags); `lastmod` from git commit dates of content files.
- Submitted via Search Console (both properties/domains as relevant) at launch; the old WP sitemap URLs left to 404→410 after cutover inventory.
## 6. Migration / cutover protection
1. **Inventory before cutover** (Phase 3 task): crawl current WP site, list indexed URLs (`site:cesnimda.co.uk`), old anchors, and any URL known to be printed/shared (esp. `/Linkedin` redirect — preserved per ROUTING_SPEC).
2. 301 map for anything with inbound value; 410 for WP cruft (`/feed/`, `/wp-json/`, `/comments/`…). Never soft-404.
3. Keep domain, keep HTTPS, no `www`/apex flip during migration (site currently canonicalises to apex — retain).
4. Verify: Search Console coverage watch for 4 weeks post-launch; link-preview spot checks in LinkedIn/Slack debuggers.
## 7. Performance & crawlability as SEO
Static HTML, content not JS-gated (crawler parity guaranteed by architecture), CWV budgets in CI (LCP < 1.8 s, CLS < 0.02) — the technical-SEO checklist is mostly satisfied *by construction*; this spec adds only the markup/meta layer above.