mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
index.html carries one set of site-wide OG tags, so every /?v=<nevent> link previewed as the same generic bitvid card -- never the video's title or thumbnail. bitvid is a static SPA and crawlers do not run JS, so the client cannot fix this. api/og.js renders the tags on demand. Nothing is pre-generated and nothing is stored: the video is a query param, not a path, so one stateless function serves every video and dist/ is byte-identical with or without it. The only caching is the CDN edge (s-maxage=300) plus a per-container memo of the admin lists. This is never load-bearing. Only crawler user-agents are rewritten to it (vercel.json), humans get a 302 to the untouched SPA, and a static/nsite deploy with no functions keeps working -- it just serves the site-wide card. Rollback is deleting the `rewrites` block. - Emits twitter:player / og:video:url pointing at embed.html?pointer=<nevent>, so a shared link plays inline on Twitter/Discord/Telegram rather than showing a still. frame-ancestors * already permits the embed. - Fails closed. A crawler never authenticates, so anything emitted is public forever in third-party caches: deleted, isPrivate, isNsfw/content-warning, blacklisted authors, and -- while whitelist mode is on -- an unavailable or empty whitelist all fall back to the generic card. - Escapes every attribute. Titles come from arbitrary nostr events and this HTML is served from bitvid's own origin; only http(s) URLs reach a meta tag. - Parses BOTH event shapes: bitvid's kind-30078 v3 JSON and the NIP-71 tag shape (kinds 21/22/34235/34236) that nostube/slidestr publish, where the title is a `title` tag and the thumbnail an `imeta image` entry. Reading only the JSON shape made every NIP-71 video fall back to the generic card. - Relay budget is 4s: a cold pool's first read measured ~3s, and 1.5s silently degraded every preview. Warm containers answer in <600ms. Admin-list identity and the relay set are imported from js/config.js, js/nostr/toolkit.js and js/nostrEventSchemas.js rather than duplicated -- a hardcoded copy of the namespace gated every preview during development, and a test now fails if any npub or wss:// literal reappears in the handler. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
45 lines
1.1 KiB
JSON
45 lines
1.1 KiB
JSON
{
|
|
"buildCommand": "npm run build",
|
|
"outputDirectory": "dist",
|
|
"installCommand": "npm install",
|
|
"git": {
|
|
"deploymentEnabled": {
|
|
"unstable": true
|
|
}
|
|
},
|
|
"rewrites": [
|
|
{
|
|
"source": "/",
|
|
"has": [
|
|
{ "type": "query", "key": "v" },
|
|
{
|
|
"type": "header",
|
|
"key": "user-agent",
|
|
"value": ".*(facebookexternalhit|Twitterbot|Slackbot|Discordbot|TelegramBot|WhatsApp|LinkedInBot|Pinterest|redditbot|Embedly|Iframely|Mastodon|Bluesky|SkypeUriPreview|vkShare|Googlebot|bingbot|Applebot|YandexBot|DuckDuckBot|Baiduspider|PetalBot|primal).*"
|
|
}
|
|
],
|
|
"destination": "/api/og"
|
|
}
|
|
],
|
|
"headers": [
|
|
{
|
|
"source": "/sw.min.js",
|
|
"headers": [
|
|
{ "key": "Cache-Control", "value": "no-cache, must-revalidate" }
|
|
]
|
|
},
|
|
{
|
|
"source": "/",
|
|
"headers": [
|
|
{ "key": "Cache-Control", "value": "no-cache, must-revalidate" }
|
|
]
|
|
},
|
|
{
|
|
"source": "/(.*\\.html)",
|
|
"headers": [
|
|
{ "key": "Cache-Control", "value": "no-cache, must-revalidate" }
|
|
]
|
|
}
|
|
]
|
|
}
|