diff --git a/src/app/utils/videoEmbed.test.ts b/src/app/utils/videoEmbed.test.ts index 42f1ee546..a5de1d7fc 100644 --- a/src/app/utils/videoEmbed.test.ts +++ b/src/app/utils/videoEmbed.test.ts @@ -216,15 +216,18 @@ test('Instagram: p / reel / tv → embed path', () => { assert.equal(getInstagramEmbed('https://www.instagram.com/someuser/'), null); }); -test('Reddit post embed → redditmedia', () => { +test('Reddit post embed → embed.reddit.com', () => { assert.equal( getRedditPostEmbed('https://www.reddit.com/r/aww/comments/abc123/cute_cat/'), 'https://embed.reddit.com/r/aww/comments/abc123/?ref_source=embed&ref=share&embed=true&theme=dark', ); assert.equal(getRedditPostEmbed('https://old.reddit.com/r/aww/comments/xyz/'), 'https://embed.reddit.com/r/aww/comments/xyz/?ref_source=embed&ref=share&embed=true&theme=dark'); assert.equal(getRedditPostEmbed('https://www.reddit.com/r/aww/'), null); // subreddit, not a post - // redd.it short link → comments-only embed (no subreddit in the redirect) - assert.equal(getRedditPostEmbed('https://redd.it/1abc23'), 'https://embed.reddit.com/comments/1abc23/?ref_source=embed&ref=share&embed=true&theme=dark'); + // redd.it short link / i.redd.it media host can't build the /r//comments/ + // path embed.reddit.com requires (a bare /comments/ 404s) → null so the caller's + // og:url fallback resolves the canonical URL first. + assert.equal(getRedditPostEmbed('https://redd.it/1abc23'), null); + assert.equal(getRedditPostEmbed('https://i.redd.it/abcd1234.jpg'), null); }); test('parseMediaEmbed: Instagram/Reddit → rich, Tidal → audio', () => { diff --git a/src/app/utils/videoEmbed.ts b/src/app/utils/videoEmbed.ts index a1b021c07..dd56896e8 100644 --- a/src/app/utils/videoEmbed.ts +++ b/src/app/utils/videoEmbed.ts @@ -344,8 +344,9 @@ export function getInstagramEmbed(url: string): string | null { } } -// --- Reddit (post embed via redditmedia — bypasses the homeserver's blocked -// preview fetch, which Reddit serves a bot-check "please wait" page to) --- +// --- Reddit (post embed via embed.reddit.com — reddit's own oEmbed widget host; +// www.redditmedia.com now 301s here. Bypasses the homeserver's blocked preview +// fetch, which Reddit serves a bot-check "please wait" page to) --- const REDDIT_EMBED_QS = '?ref_source=embed&ref=share&embed=true&theme=dark'; @@ -353,15 +354,14 @@ export function getRedditPostEmbed(url: string): string | null { try { const u = new URL(url); const h = u.hostname.replace(/^(www|old|new|np|i)\./, ''); - // redd.it/ short link → reddit.com/comments/ (no subreddit needed). - if (h === 'redd.it') { - const id = u.pathname.replace(/^\/+|\/+$/g, '').split('/')[0]; - return id ? `https://embed.reddit.com/comments/${id}/${REDDIT_EMBED_QS}` : null; - } + // embed.reddit.com ONLY renders the /r//comments/ path (verified against + // reddit's own embed widgets.js). A bare /comments/ — all we could build from a + // redd.it short link or an i./v.redd.it media host — serves a "not found" page, so + // return null for those and let the caller's og:url fallback resolve the canonical + // /r//comments/ URL (from the redirect) before re-parsing into a real embed. if (h !== 'reddit.com') return null; const m = u.pathname.match(/^\/r\/([A-Za-z0-9_]+)\/comments\/([A-Za-z0-9]+)/); if (!m) return null; - // embed.reddit.com is the current host (www.redditmedia.com now 301s here). return `https://embed.reddit.com/r/${m[1]}/comments/${m[2]}/${REDDIT_EMBED_QS}`; } catch { return null;