Avatar
Show a user image with an automatic fallback while it loads or when it fails.
import { Div } from "@implementjs/core";
import { Avatar, AvatarFallback, AvatarImage } from "@/lib/components/ui/avatar";
export default function AvatarDemo() {
return Div(
{ class: "flex flex-row flex-wrap items-center gap-8" },
Avatar(
AvatarImage({ src: "https://github.com/ieedan.png", alt: "@ieedan" }),
AvatarFallback("AB"),
),
Avatar(
AvatarImage({ src: "https://github.com/broken-link-404.png/nope", alt: "broken" }),
AvatarFallback("ER"),
),
Div(
{
class:
"flex -space-x-2 *:data-[slot=avatar]:ring-2 *:data-[slot=avatar]:ring-background *:data-[slot=avatar]:grayscale",
},
Avatar(
AvatarImage({ src: "https://github.com/ieedan.png", alt: "@ieedan" }),
AvatarFallback("AB"),
),
Avatar(
AvatarImage({ src: "https://github.com/github.png", alt: "@github" }),
AvatarFallback("GH"),
),
Avatar(
AvatarImage({ src: "https://github.com/shadcn.png", alt: "@shadcn" }),
AvatarFallback("CN"),
),
),
);
}An avatar renders an image with a fallback for when the image is loading or unavailable. Avatar is the root, AvatarImage is the picture, and AvatarFallback is what shows until the image has actually loaded (initials, an icon, anything).
import { Avatar, AvatarFallback, AvatarImage } from "@implementjs/primitives";
Avatar(AvatarImage({ src: "https://github.com/ieedan.png", alt: "@ieedan" }), AvatarFallback("AB"));
Each part accepts optional props and children — pass a props object when you need attributes, or pass children directly. See createComponent. Extra props are forwarded onto the underlying Div, Img, or Span.
Loading status
The root tracks a loading status: "loading", "loaded", or "error". The image is preloaded off-DOM, so the fallback stays visible until the browser has real pixels — no broken-image flash. The image is hidden until the status is "loaded", and the fallback is hidden once it is.
If src is missing or the request fails, the status becomes "error" and the fallback simply stays.
Pass onLoadingStatusChange to observe it:
Avatar(
{ onLoadingStatusChange: (status) => console.log(status) },
AvatarImage({ src }),
AvatarFallback("AB"),
);
A reactive src re-runs the load: pass a signal and swapping the value puts the avatar back into "loading" until the new image resolves.
Delaying the fallback swap
On a fast connection the fallback can flash for a frame before the image appears. delayMs waits that many milliseconds after the image loads before showing it:
Avatar({ delayMs: 600 }, AvatarImage({ src }), AvatarFallback("AB"));
Styling
Every part sets a data-avatar-* attribute so you can target it in CSS, and all three expose data-status with the current loading status:
Avatar(
{ class: "relative flex size-8 shrink-0 overflow-hidden rounded-full" },
AvatarImage({ src, class: "aspect-square size-full" }),
AvatarFallback({ class: "flex size-full items-center justify-center bg-muted" }, "AB"),
);
Visibility is handled for you with inline display, so a flex class on the fallback is safe — it only applies while the fallback is actually shown.
API Reference
Avatar
The root. Tracks the image's loading status for the parts inside it. Renders a Div; extra props are forwarded onto it.
| Prop | Type | Default | Description |
|---|---|---|---|
delayMs | number | 0 | How long to wait after the image loads before showing it, preventing a flash on fast connections. |
onLoadingStatusChange | (status: AvatarLoadingStatus) => void | — | Called whenever the loading status changes. |
| Data attribute | Value |
|---|---|
[data-avatar-root] | Present |
[data-status] | "loading" | "loaded" | "error" |
AvatarImage
The picture. Preloaded off-DOM and only shown once loaded; a reactive src re-runs the load. Renders a Img; extra props are forwarded onto it.
| Data attribute | Value |
|---|---|
[data-avatar-image] | Present |
[data-status] | "loading" | "loaded" | "error" |
AvatarFallback
Shown until the image has loaded — initials, an icon, anything. Renders a Span; extra props are forwarded onto it.
| Data attribute | Value |
|---|---|
[data-avatar-fallback] | Present |
[data-status] | "loading" | "loaded" | "error" |



