From c0d006a5fc9a8fa008abf2a126762537499e90a8 Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Tue, 28 Jul 2026 14:48:32 -0400 Subject: [PATCH] [og] Derive the preview origin from the request SITE_ORIGIN is a constant defaulting to https://bitvid.network, so the unstable deployment advertised production's canonical URL and, worse, a twitter:player pointing at production's embed -- testing a preview link silently exercised the live site. Build shareUrl, embedUrl and the fallback card from the request's own proto+host instead, so every deployment (production, unstable, preview) is self-consistent. BITVID_SITE_ORIGIN remains the fallback when the host header is absent. Co-Authored-By: Claude Opus 5 (1M context) --- api/og.js | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/api/og.js b/api/og.js index 2420df71..636b10bb 100644 --- a/api/og.js +++ b/api/og.js @@ -135,11 +135,17 @@ export default async function handler(req, res) { const requestUrl = new URL(req.url || "/", `${proto}://${host}`); const pointer = requestUrl.searchParams.get("v") || ""; + // Derive the origin from the REQUEST, not from a constant. Otherwise every + // non-production deployment (unstable, previews) advertises production's + // canonical URL and — worse — a twitter:player pointing at production's + // embed, so testing a preview link silently exercises the live site. + const origin = `${proto}://${host}`; + const shareUrl = pointer - ? `${SITE_ORIGIN}/?v=${encodeURIComponent(pointer)}` - : SITE_ORIGIN; + ? `${origin}/?v=${encodeURIComponent(pointer)}` + : origin; const embedUrl = pointer - ? `${SITE_ORIGIN}/embed.html?pointer=${encodeURIComponent(pointer)}` + ? `${origin}/embed.html?pointer=${encodeURIComponent(pointer)}` : ""; const renderFallback = (reason) => { @@ -149,7 +155,11 @@ export default async function handler(req, res) { res.setHeader("Cache-Control", "public, s-maxage=300, stale-while-revalidate=600"); res.setHeader("X-Bitvid-OG", reason); res.status(200).send( - renderOgHtml({ video: null, shareUrl, fallback: FALLBACK }) + renderOgHtml({ + video: null, + shareUrl, + fallback: { ...FALLBACK, url: origin, image: `${origin}/assets/jpg/bitvid.jpg` }, + }) ); }; @@ -242,9 +252,15 @@ export default async function handler(req, res) { res.setHeader("Content-Type", "text/html; charset=utf-8"); res.setHeader("Cache-Control", "public, s-maxage=300, stale-while-revalidate=600"); res.setHeader("X-Bitvid-OG", "video"); - res - .status(200) - .send(renderOgHtml({ video, shareUrl, embedUrl, fallback: FALLBACK, gate })); + res.status(200).send( + renderOgHtml({ + video, + shareUrl, + embedUrl, + fallback: { ...FALLBACK, url: origin, image: `${origin}/assets/jpg/bitvid.jpg` }, + gate, + }) + ); } catch (err) { renderFallback("error"); } finally {