# Fading Image

An image that fades in on load with a skeleton and error fallback.

## Installation

```bash
npx shadcn@latest add https://landorui.landorestate.com/r/fading-image.json
```

[Registry JSON](https://landorui.landorestate.com/r/fading-image.json)

## Preview

```tsx
import { FadingImage } from "@/components/ui/fading-image";

export function Preview() {
  return (
    <FadingImage
      src="https://images.unsplash.com/photo-1501785888041-af3ef285b470?w=600"
      alt="Mountain landscape"
      containerClassName="size-48 rounded-lg"
    />
  );
}
```


## Source

### ui/fading-image.tsx

```tsx
"use client";

import { ImageOff } from "lucide-react";
import * as React from "react";

import { cn } from "@/lib/utils";

type FadingImageProps = React.ComponentProps<"img"> & {
  containerClassName?: string;
};

const FadingImage = React.memo(function FadingImage({
  src,
  alt,
  className,
  containerClassName,
  ...props
}: FadingImageProps) {
  const [loadedSrc, setLoadedSrc] = React.useState<string | null>(null);
  const [failedSrc, setFailedSrc] = React.useState<string | null>(null);
  const loaded = loadedSrc === src;
  const failed = failedSrc === src;

  return (
    <div className={cn("relative overflow-hidden", containerClassName)}>
      {failed ? (
        <div className="absolute inset-0 flex items-center justify-center bg-muted" aria-hidden>
          <ImageOff className="size-6 text-muted-foreground/40" />
        </div>
      ) : (
        <div
          className={cn(
            "absolute inset-0 bg-muted transition-opacity duration-300",
            loaded ? "pointer-events-none opacity-0" : "animate-pulse",
          )}
          aria-hidden
        />
      )}
      <img
        src={src}
        alt={alt}
        data-slot="fading-image"
        className={cn(
          "size-full object-cover transition-opacity duration-300",
          loaded && !failed ? "opacity-100" : "opacity-0",
          className,
        )}
        onLoad={() => {
          setLoadedSrc(src ?? null);
          setFailedSrc(null);
        }}
        onError={() => setFailedSrc(src ?? null)}
        {...props}
      />
    </div>
  );
});

export { FadingImage };
```



## Usage

An image that fades in on load, showing a pulsing skeleton while loading and an
icon fallback if the source fails.

```tsx
import { FadingImage } from "@/components/ui/fading-image";
```

