ReviewOS

stacks/bench-review

seo: Open Graph / Twitter cards are client-JS only — social scrapers see nothing, and og:image 404s

#60
Closed glennmichael123 opened this 10 days ago ·
10 days ago

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 only public/images/og-image.png exists — the referenced file 404s.
  • The review permalink (resources/views/article/[id].stx → ArticleView) — the most shareable unit — has no share affordance, while ProfileHeader.stx:99-115 and Blog/Blog.stx:5-12 already 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:image points 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).

9 days ago

Fixed. The static head now carries the full set — dist/judges.html has og:title, og:image and twitter:card, injected at build time by app/Helpers/seoPages.ts / entitySeo.ts rather than appended at hydration, so scrapers that run no JS see them. public/images/og-image.png exists, so the 404 is gone too.

Root cause of the original symptom is written up in #89: @extends discards the server-scope runtime head, so useSeoMeta never reached these pages at all. The build-time injection is the deliberate workaround, not an accident.

Sign in to comment on this issue.