Skip to content

feat(og): server-rendered project and home social cards (fixes #24) - #51

Closed
astra-intelligence wants to merge 1 commit into
devodii:mainfrom
astra-intelligence:feat/og-project-cards
Closed

astra-intelligence wants to merge 1 commit into
devodii:mainfrom
astra-intelligence:feat/og-project-cards

Conversation

@astra-intelligence

Copy link
Copy Markdown

Summary

Closes #24. A link like https://hackproof-six.vercel.app/project/repo:Klorenn/LOOT pasted into Discord, X, Slack, Telegram or iMessage now renders a real preview card instead of a blank link. The SPA is untouched for normal visitors.

What changed

  • apps/web/api/og.ts — crawler-facing HTML with og:title, og:description, og:image (+ spread/twitter tags), HTML-escaped, for /project/* and the home page. 404 for unknown project ids.
  • apps/web/api/og.png.ts — renders a 1200×630 PNG with satori + @resvg/resvg-js from GET /api/projects/{id}:
    • project card: repo name, tagline/description, contracts deployed count, evidence tier (Verified on-chain / Code only), Genesis/Scale track, stars/forks/language
    • home default card: the timeline chart (contracts deployed per hour), same data as the site's /api/timeline
  • apps/web/vercel.json — rewrites /project/* and / requests from known link-preview crawler user agents (Discordbot, Twitterbot, facebookexternalhit, LinkedInBot, Slackbot, TelegramBot, WhatsApp, Pinterest, etc.) to /api/og. Everything else keeps the SPA.
  • apps/web/api/_og-lib.tsx + bundled Outfit 400/600 fonts (fontsource latin TTFs, ~33 KB each) so satori renders the site's own brand type.
  • apps/web/index.html — static og:/twitter: meta defaulting to the timeline card for crawlers that bypass the UA list.
  • pnpm-workspace.yaml — set the esbuild build-approval placeholder left by pnpm approve-builds to true (esbuild is a transitive dev dep of @vercel/node/vite; the postinstall just validates the binary).

The card pulls data from the same Railway API the site uses. API_URL env (or RAILWAY_API_URL) overrides the default production URL.

Verification

  • pnpm lint — 0 errors (4 pre-existing warnings, unchanged)
  • pnpm format:check — clean
  • pnpm build — green (Vite + publish-data)
  • Both cards rendered 1200×630 against the live Railway API and passed vision QA (no clipped text, brand tokens, footer row)
  • HTML handler: escaping verified with <script> payload; missing project returns 404

Happy to share rendered card previews, or you can see them live by hitting /api/og.png?project=repo%3AKlorenn%2FLOOT and /api/og.png after deploy.

Adds server-side Open Graph support for project links so Discord, X, Slack
and other crawlers see a real card instead of a blank preview.

- apps/web/api/og.ts: crawler-facing HTML with og:title/description/image
  (project + home variants), HTML-escaped values, 404 handling.
- apps/web/api/og.png.ts: renders 1200x630 PNG with satori + resvg from
  /api/projects/{id}; project card shows name, tagline, contracts count,
  evidence tier and hackathon; home default card shows the timeline chart.
- apps/web/vercel.json: rewrites /project/* and / from known link-preview
  crawler user agents to /api/og; normal visitors keep the SPA.
- apps/web/api/_og-lib.tsx + bundled Outfit 400/600 fonts (fontsource).
- index.html: static og/twitter meta defaulting to the timeline card.
- pnpm-workspace.yaml: approve esbuild build (placeholder left by pnpm approve-builds).

Verified: pnpm lint, format:check and build green; both cards render 1200x630
against the live Railway API and pass vision QA.
@vercel

vercel Bot commented Oct 31, 2026

Copy link
Copy Markdown

@astra-intelligence is attempting to deploy a commit to the Payroutes OSS Team on Vercel.

A member of the Team first needs to authorize it.

@devodii devodii closed this Nov 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OG image per project page

2 participants