// Per-video OpenGraph / Twitter-player rendering for crawlers. // // bitvid is a static SPA: index.html carries one set of site-wide OG tags, so // every `/?v=` link previewed as the same generic bitvid card. Crawlers // don't run JS, so the client can't fix that — this module renders the tags a // crawler needs, and a thin host adapter (api/og.js on Vercel) feeds it. // // PURE by design: no network, no host globals. All I/O lives in the adapter so // the escaping and gating rules below stay unit-testable. // // Rollback: remove the crawler rewrite from vercel.json. The static site keeps // serving its existing tags and nothing else changes — this is never on the // path of a real user's page load, and `npm run archive` (nsite) is unaffected. // Player card dimensions. Twitter refuses a player card without explicit // dimensions, and 16:9 matches bitvid's embed shell. export const DEFAULT_PLAYER_WIDTH = 1280; export const DEFAULT_PLAYER_HEIGHT = 720; const MAX_TITLE_LENGTH = 120; const MAX_DESCRIPTION_LENGTH = 200; /** * Escape a value for use inside a double-quoted HTML attribute. * * Titles and descriptions come from arbitrary nostr events — treat every one as * hostile. A title of `">