Problem
Zero og:*/twitter:* meta exists in any static head — useSeoMeta appends meta via document.createElement at hydration, invisible to the FB/X/Slack/iMessage scrapers that never run JS. Shared judge/review links render as bare URLs.
Findings
- Five surfaces reference
/images/og-default.jpg(resources/views/home.stx:21,25,resources/components/Bench/Judge/ProfileHeader.stx:73,77,Bench/ArticleView.stx:32,36,Bench/Court/CourtHeader.stx:49,53,Bench/User/ReviewerProfile.stx:23,27), but onlypublic/images/og-image.pngexists — the referenced file 404s. - The review permalink (
resources/views/article/[id].stx→ ArticleView) — the most shareable unit — has no share affordance, whileProfileHeader.stx:99-115andBlog/Blog.stx:5-12already implement the navigator.share + clipboard pattern.
Acceptance criteria
- OG/Twitter meta present in the static HTML of built pages (verifiable by grepping dist heads with JS disabled)
og:imagepoints to an existing 1200×630 asset- Review permalink page gets a share button matching the ProfileHeader pattern
Split out from the SEO bundle of the 2026-06-10 production-readiness audit. Related: stacksjs/stx#1756 (static head injection).