fix(ui): robust avatars — no-referrer + graceful fallback

Channel/account avatars come from Google's image CDNs (yt3.ggpht.com,
lh3.googleusercontent.com). On a feed page dozens load at once; the CDN
rate-limits the referrer-bearing burst (429), so a random subset rendered the
browser's broken-image icon (the URLs themselves are valid — verified 200).

Add a shared <Avatar> that sets referrerPolicy="no-referrer" (which the CDNs
serve without throttling) and falls back to a neutral initial placeholder on
error instead of the broken-image icon. Use it for video-card, player, channel
manager, header and settings avatars.
This commit is contained in:
npeter83 2026-06-12 18:01:43 +02:00
parent 473171d1b4
commit a640b181ee
6 changed files with 77 additions and 29 deletions

View file

@ -4,6 +4,7 @@ import type { FeedFilters, Me } from "../lib/api";
import type { Page } from "../lib/urlState";
import SyncStatus from "./SyncStatus";
import NotificationCenter from "./NotificationCenter";
import AvatarImg from "./Avatar";
export default function Header({
me,
@ -70,12 +71,12 @@ export default function Header({
}
function Avatar({ me, className = "" }: { me: Me; className?: string }) {
return me.avatar_url ? (
<img src={me.avatar_url} alt="" className={`rounded-full ${className}`} />
) : (
<div className={`rounded-full bg-card grid place-items-center font-semibold ${className}`}>
{(me.display_name?.[0] ?? me.email[0] ?? "?").toUpperCase()}
</div>
return (
<AvatarImg
src={me.avatar_url}
fallback={me.display_name ?? me.email}
className={`rounded-full ${className}`}
/>
);
}