this repo has no description
10
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: use same-origin banner proxy for project og:image (composer thumbnail)

Homepage link cards used /og-hero.png (~320KB, atmosphereaccount.com).
Project pages used full-size cdn.bsky.app banner URLs (~650KB+), which
matched Cardyb extract but often showed text-only cards in the Bluesky
composer. Use absolute /api/registry/banner/{did} for og/twitter image
metadata so embeds follow the same origin/size pattern as the homepage.

Remove unused bsky CDN banner helpers from lib/avatar.ts.

Made-with: Cursor

+10 -47
-32
lib/avatar.ts
··· 6 6 export function bskyCdnAvatarUrl(did: string, cid: string): string { 7 7 return `https://cdn.bsky.app/img/avatar/plain/${did}/${cid}`; 8 8 } 9 - 10 - /** 11 - * Same proxy, banner variant. Bluesky exposes a separate path with 12 - * banner-friendly resizing (16:9-ish, larger). Rendered at the top of 13 - * project pages and used as the OpenGraph / Twitter card image when 14 - * the page URL is shared. 15 - */ 16 - export function bskyCdnBannerUrl( 17 - did: string, 18 - cid: string, 19 - mime = "jpeg", 20 - ): string { 21 - const fmt = mime === "image/png" ? "png" : "jpeg"; 22 - return `https://cdn.bsky.app/img/banner/plain/${did}/${cid}@${fmt}`; 23 - } 24 - 25 - /** 26 - * Returns true when a PDS URL belongs to Bluesky's own infrastructure 27 - * (bsky.social or *.bsky.network). Banners on Bluesky-hosted accounts can be 28 - * served straight from cdn.bsky.app, which is on Bluesky's own domain 29 - * allowlist for link-preview images. Custom-PDS banners must go through our 30 - * own proxy instead. 31 - */ 32 - export function isBlueskyPds(pdsUrl: string | null | undefined): boolean { 33 - if (!pdsUrl) return false; 34 - try { 35 - const host = new URL(pdsUrl).hostname; 36 - return host === "bsky.social" || host.endsWith(".bsky.network"); 37 - } catch { 38 - return false; 39 - } 40 - }
+10 -15
routes/explore/[handle].tsx
··· 18 18 getProfileByHandle, 19 19 type ProfileRow, 20 20 } from "../../lib/registry.ts"; 21 - import { bskyCdnBannerUrl, isBlueskyPds } from "../../lib/avatar.ts"; 22 21 import { 23 22 getOwnReview, 24 23 getReviewSummary, ··· 91 90 const pageTitle = `${profile.name} on Atmosphere Account`; 92 91 const pageDescription = profile.description || 93 92 messages.detail.missingProfile; 94 - // Bluesky's link-preview crawler only proxies images from its own 95 - // allowlisted domains. For accounts hosted on Bluesky's PDS, use 96 - // cdn.bsky.app directly (always accessible). For custom-PDS accounts, 97 - // fall back to our own proxy which fetches the blob from their PDS. 93 + // Always use our own absolute banner URL for og:image (same origin as 94 + // /og-hero.png on the homepage). Raw cdn.bsky.app banners can be ~650KB+ 95 + // and wide (e.g. 3000×1000); the homepage card uses a smaller static PNG 96 + // and shows a thumbnail in the Bluesky composer, while the CDN URL often 97 + // produced a text-only link card. Cardyb successfully fetches this proxy 98 + // and normalizes dimensions for embeds. 98 99 const ogImageUrl = profile.bannerCid 99 - ? isBlueskyPds(profile.pdsUrl) 100 - ? bskyCdnBannerUrl( 101 - profile.did, 102 - profile.bannerCid, 103 - profile.bannerMime ?? undefined, 104 - ) 105 - : new URL( 106 - `/api/registry/banner/${encodeURIComponent(profile.did)}`, 107 - ctx.url.origin, 108 - ).href 100 + ? new URL( 101 + `/api/registry/banner/${encodeURIComponent(profile.did)}`, 102 + ctx.url.origin, 103 + ).href 109 104 : undefined; 110 105 ctx.state.pageMeta = { 111 106 title: pageTitle,