···79798080If the key is not set, search falls back gracefully to lexical title ranking.
81818282+## Open Graph preview support (Bluesky / Twitter)
8383+8484+This repo now supports crawler-friendly OG tags in two layers:
8585+8686+- Default static OG card from `public/og-default.png`.
8787+- Per-video HTML metadata at `functions/video/[didParam]/[rkeyParam].ts` so shared `/video/:did/:rkey` links return server-rendered meta tags for crawlers.
8888+8989+Why this works on Cloudflare Pages:
9090+9191+- Social crawlers usually do not execute SPA JavaScript.
9292+- Cloudflare Pages Functions can return HTML with route-specific `<meta property="og:*">` tags before the SPA loads.
9393+9494+### Cost profile / free-tier impact
9595+9696+- This setup is low-cost because image generation is static (`og-default.png`) and reused.
9797+- Per-video function requests fetch one `com.atproto.repo.getRecord` for title/description and then inject tags into `index.html`.
9898+- No per-request video frame extraction, no external image API, and no persistent storage writes.
9999+100100+### Verify previews after deploy
101101+102102+1. Open any direct video URL and confirm source HTML includes route-specific `og:title`, `og:description`, and `og:url`.
103103+2. Validate with social debuggers:
104104+ - Twitter/X Card Validator: `https://cards-dev.twitter.com/validator`
105105+ - OpenGraph checker: `https://www.opengraph.xyz/`
106106+3. Paste a video URL into Bluesky compose and confirm preview card appears.
107107+82108### Freshness behavior
8310984110- Newly uploaded VODs appear immediately in results because the search function overlays a live catalog