SEO content & IA: Twin Cities positioning, service pages, about/contact, redirect pattern - #54
Open
dralgorhythm wants to merge 8 commits into
Open
SEO content & IA: Twin Cities positioning, service pages, about/contact, redirect pattern#54dralgorhythm wants to merge 8 commits into
dralgorhythm wants to merge 8 commits into
Conversation
…irect stub
Nests the fourth service under /services/* and takes the searched slug
('career coaching'; 'guidance' is a zero-volume phrase). Safe to move
now: months of 404 plus the homepage-canonical bug left the old URL with
minimal equity. Retitled for 'tech career coach minneapolis', local
hero sentence + Twin Cities FAQ, discovery-call CTAs to /contact,
Service schema + breadcrumb, first-person voice in metadata.
New reusable static-redirect pattern (GitHub Pages cannot 301):
lib/redirects.ts registry + RedirectPage stub emitting an instant meta
refresh with canonical pointing at the destination. The old URL keeps a
stub that is never sitemapped or internally linked; the metadata-policy
test now computes each page's route, requires canonical === route for
real pages, and requires stubs to canonicalize to their registered
destination. e2e verifies the browser lands on the new page.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
/services hub (four offering cards, solo positioning, local intro) plus
dedicated pages for the three consulting lines, each targeting one
primary query: software-consulting ('software consultant minneapolis'),
ai-consulting ('ai consulting minneapolis'), and
engineering-practice-improvement ('engineering process improvement
consultant'). Every page: distinct 600-900 word copy in first person, a
deliberately different local angle (onsite architecture sessions / past-
the-demo-phase AI adoption / embedded practice change), six real-search
FAQs with FAQPage schema, Service schema, breadcrumb, own OG card,
related-services triangle, and discovery-call CTA. The AI page cites the
agent-coordination essay as proof of practice. Sitemap gains all four
routes in the same PR that ships them (health-check contract).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Home becomes the metro category page: 'Twin Cities Software Consulting' title (keyword-first for a weak-brand domain), 'Software Consulting in the Twin Cities' h1, founder hero linking /about, discovery-call CTA, four service cards from a shared config (also consumed by the hub), an AI-native differentiator section citing the agent-coordination essay, and exactly one local trust line. /about is the E-E-A-T anchor — Jordan Winters, Minneapolis, beliefs, solo working model, proof links — and the Person schema url now points there. /contact ships LinkedIn-primary (email lands in the gated commit) with the free-discovery-call framing and the NAP line. Sitemap gains /about and /contact. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Nav becomes home/services/coaching/blog/about/contact (experiments moves to the footer — 12 of 13 are noindexed stubs). The footer grows three link columns (Services x4 / Site / Connect) plus one plain NAP line, fixing the sitewide orphaning of a footer that previously held only social links. Root default title/description flip to the Twin Cities positioning (deliberately held out of PR1), authors credit Jordan Winters, and the WebSite/Organization schema description follows via siteConfig. Blog: index description drops 'the team' voice; the post's title tag targets 'Coordinating AI Coding Agents' via a new seoTitle field (h1 unchanged), gains a byline linking /about, repoints its intro Engineering-Practice-Improvement link from LinkedIn to the service page, and closes with an ai-consulting pointer. New AI/feed discovery surfaces: public/llms.txt and a hand-rolled static /rss.xml (linked from the layout head and blog index). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
MERGE GATE: requires the Namecheap Email Forwarding alias 'jordan' to exist and receive a test message first (~5 min in the Namecheap dashboard; MX/SPF already live). Drop this commit if merging before the alias is confirmed — everything else in the PR stands alone. Adds the email (single source: siteConfig.email) to the footer Connect column, the contact page as the primary CTA, the home closing CTA, the career-coaching contact section, and the ProfessionalService schema's email property. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
next-image-export-optimizer rewrites its hashes JSON 4-space-indented on every build, while Biome's formatter gate demands 2-space — so any local build broke the next lint run (the PR auto-fix bot and a manual fix had each patched the symptom once already). Generated build output doesn't belong in the style gate; the committed copy now matches the optimizer's own output so builds are no-ops on it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The footer now also links Blog, so the unscoped getByRole('link')
tripped Playwright strict mode. aria-label='Main' on the nav is the
a11y-correct disambiguator.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
🔍 Preview Build ReadyBuild Status: ✅ Success 📦 Preview artifact uploaded - check the Actions tab to download.
|
Adversarial content review against the resume and LinkedIn found the
copy drifting from the record and the voice. Corrections:
Facts. 'Nearly 20 years' (8 places) becomes 'over a decade' - the
record starts in 2015 and his own headline says 'a decade.' The stale
'I lead Engineering Practice Improvement for a living' claims move to
past-tense portfolio framing (that role ended with the Thrivent
contract in Jan 2026), and the blog byline drops the role label.
Schema: foundingDate corrects from a fabricated 2024 to 2025-03-01
(LinkedIn), jobTitle becomes Software & Infrastructure Consultant, and
knowsAbout gains the real hard skills (AWS/GCP, Terraform, ECS/K8s,
Datadog/ELK, FinOps, agentic AI).
Positioning. The software-consulting page drops the invented app-shop
narrative ('rescue work is a specialty' had no basis) for the evidenced
specialty mix: 0-to-1 platform foundations, architecture, and
infrastructure modernization with real numbers (70% legacy cost cut,
>75% faster builds/deploys, >$1.5M/yr cloud savings, empty repo to
public beta in six months). The AI page adds its strongest proof (six-
month 0-to-beta with 90% gross margin, regulated-environment LLM
patterns); the practice page cites the founded Observability practice
and the +30%/-50% scrum outcomes. About restores the essay's named
frameworks (Product Operating Model, Agile, DevOps) that an earlier
rewrite had blurred into aphorisms, and adds the real career spine.
Voice. All 86 user-facing em dashes replaced with restructured
sentences or spaced hyphens (his written style; his own essay contains
zero em dashes), including the experiment pages. Seven rhetorical-
question CTAs become declarative, double-dash asides and stacked
antithesis removed, duplicate 'no handoffs' phrasing trimmed. A new
policy test bans em dashes in page sources permanently.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
🔍 Preview Build ReadyBuild Status: ✅ Success 📦 Preview artifact uploaded - check the Actions tab to download.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PR 2 of 2 of the Twin Cities SEO update (plan:
artifacts/plan_seo_optimization.md), branched from currentmain(includes merged #53). All positioning/copy changes land here so titles and content arrive together.Information architecture
/services/career-coaching(searched slug; "guidance" is zero-volume) with a new reusable static-redirect pattern for GitHub Pages:lib/redirects.tsregistry + a stub at/career-guidanceemitting an instant meta refresh with canonical → destination. Stubs are never sitemapped or internally linked; the metadata-policy test enforces stub correctness./serviceshub + three new service pages, each owning one primary query with 600–900 words of distinct first-person copy, a deliberately different local angle, six real-search FAQs (FAQPage schema), Service schema, breadcrumbs, own OG card, and a related-services triangle:/services/software-consulting→ software consultant minneapolis/services/ai-consulting→ ai consulting minneapolis (cites the agent-coordination essay as proof of practice)/services/engineering-practice-improvement→ engineering process improvement consultantTwin Cities Software Consulting, founder hero →/about, discovery-call CTA, four service cards (shared config with the hub), AI-native differentiator section, exactly one local trust line./about(E-E-A-T anchor — Jordan Winters, Minneapolis, beliefs, solo model; Person schemaurlrepoints here) and/contact(free 30-min discovery call framing + NAP line)./about, intro link repointed from LinkedIn to the practice-improvement service page, closing pointer to/services/ai-consulting; index description drops the fake "team" voice.public/llms.txt+ hand-rolled static/rss.xml(linked in head + blog index) — pairs with SEO technical foundation: canonicals, local-entity schema, sitemap/robots, per-route OG images #53's decision to welcome AI crawlers.feat(seo): publish jordan@bidwell.info contact emailpublishes the address in the footer, contact page, home, career-coaching, and org schema. Before merging, create the Namecheap Email Forwarding alias (jordan→ your inbox; ~5 min, MX/SPF already live — Namecheap dashboard → bidwell.info → Email Forwarding) and confirm a test email arrives. To merge sooner, drop that one commit — everything else stands alone with LinkedIn-primary CTAs.Also includes a root-cause fix for a recurring annoyance: the image optimizer rewrites its hashes JSON in a style Biome rejects, so every local build broke the next lint run (the auto-fix bot had already patched the symptom once on #53). The generated file is now excluded from the style gate.
Guardrails honored
No suburb doorway pages, no fake reviews/aggregateRating, no "our team" plurality, geo modifier once per page, distinct local paragraphs (not templated swaps), varied internal anchors.
Test plan
npm run qa:fullgreen (type-check, Biome, coverage, production build)npm run test:e2e13/13 — including the redirect-stub browser flow, rss/llms resolution, and the SEO invariants suite/career-guidanceredirecting in a browser🤖 Generated with Claude Code