All pages

Components

Avatar

A member's picture, with the legacy default silhouette behind it. A missing source and a URL that 404s land on the same fallback.

Usage

src takes an OSS object key or an absolute URL — keys resolve against the bucket with x-oss-process resize parameters, absolute URLs pass through untouched. Not next/image: avatars arrive with server-side resizing already in the URL, so a second optimizer pass adds latency for nothing. Shape and size come from className.

import { Avatar } from "@/components/base/avatar";

<Avatar src={member.avatar} width={64} className="size-8 rounded-full" />

Fallback

A broken avatar is common enough — a deleted OSS object, a third-party URL that rots — that the component is a client component purely for onError. The failure is keyed by URL rather than a bare boolean, so a later src gets its own chance to load instead of inheriting the previous one's failure. The default is a white silhouette, inverted on the light theme — and only when it is actually the one showing, since inverting a real photograph would be its own kind of broken.

Sizing

width feeds the OSS resize parameter, not the layout: pass roughly twice the rendered size, and let className set the box.