From 8bba08653ce5e89cfef369d245f903151f46ffd6 Mon Sep 17 00:00:00 2001 From: "prompt.ac/@jeffrey" Date: Mon, 28 Sep 2026 14:43:58 -0700 Subject: [PATCH] og-preview: Reddit cards fall back to what the URL says Reddit turns lith's datacenter address away, so the oEmbed lookup that works from a laptop fails in production. When it does, the card shows the subreddit and, for /comments// links, the title spelled out of the slug, instead of a bare "www.reddit.com". Co-Authored-By: Claude Opus 5.5 --- system/netlify/functions/og-preview.mjs | 26 +++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/system/netlify/functions/og-preview.mjs b/system/netlify/functions/og-preview.mjs index ffe5cd7b1f..b27cd5ae24 100644 --- a/system/netlify/functions/og-preview.mjs +++ b/system/netlify/functions/og-preview.mjs @@ -280,20 +280,30 @@ async function providerPreview(url) { } if (hostIs(url, "reddit.com", "redd.it")) { - // Share links (/r/x/s/abc) are redirects; the post URL is in Location. + // Reddit turns datacenter addresses away, lith's included, so every + // step here may fail; the card then falls back to what the URL says. let post = url.href; if (/\/s\/[\w-]+/.test(url.pathname) || url.hostname === "redd.it") { const hop = await fetch(url.href, { method: "HEAD", redirect: "manual", - headers: { "User-Agent": PROVIDER_UA }, signal: AbortSignal.timeout(FETCH_TIMEOUT_MS) }); - const location = hop.headers.get("location"); + headers: { "User-Agent": PROVIDER_UA }, signal: AbortSignal.timeout(FETCH_TIMEOUT_MS) }).catch(() => null); + const location = hop?.headers.get("location"); if (location) post = new URL(location, url).href.split("?")[0]; } - const data = await getJson(`https://www.reddit.com/oembed?url=${encodeURIComponent(post)}`); + const sub = post.match(/\/r\/(\w+)/)?.[1]; + const data = await getJson(`https://www.reddit.com/oembed?url=${encodeURIComponent(post)}`).catch(() => null); const title = data?.html?.match(/([^<]+)<\/a>/)?.[1]; - if (!title) return null; - const sub = post.match(/\/r\/([\w]+)/)?.[1]; - return { url: url.href, title: decodeHtmlEntities(title), image: null, description: null, - siteName: byline("Reddit", sub && `r/${sub}`, data.author_name && `u/${data.author_name}`), + if (title) { + return { url: url.href, title: decodeHtmlEntities(title), image: null, description: null, + siteName: byline("Reddit", sub && `r/${sub}`, data.author_name && `u/${data.author_name}`), + favicon: "https://www.redditstatic.com/shreddit/assets/favicon/192x192.png" }; + } + if (!sub) return null; + // /comments// spells the title in lowercase with underscores. + const slug = post.match(/\/comments\/\w+\/([^/?#]+)/)?.[1]; + let fromSlug = null; + try { fromSlug = slug && decodeURIComponent(slug).replace(/_/g, " "); } catch {} + return { url: url.href, title: fromSlug || `r/${sub}`, image: null, description: null, + siteName: byline("Reddit", fromSlug && `r/${sub}`), favicon: "https://www.redditstatic.com/shreddit/assets/favicon/192x192.png" }; } -- 2.51.2