---
title: Image
description: An optimized image component with built-in lazy loading and responsive image support using the picture element
---

```tsx
'use client';

import { Image } from '@/ui/Image';

export function ImageDemo() {
  return (
    <Image
      alt="Placeholder image"
      className="rounded-lg"
      src="https://images.unsplash.com/photo-1682687220742-aba13b6e50ba?w=800&h=600&fit=crop"
    />
  );
}
```

## Installation

Using the CLI:

```bash
npx shadcn@latest add https://develop.trident-ui.pro.clubmed/r/image.json
```

Or manually, copy the following code into `/ui/image.tsx`:

```tsx
import type { ComponentPropsWithoutRef, FunctionComponent, SourceHTMLAttributes } from 'react';

export interface ImageProps extends ComponentPropsWithoutRef<'img'> {
  lazyLoad?: boolean;
  src: string;
  sources?: SourceHTMLAttributes<HTMLSourceElement>[];
}

export const Image: FunctionComponent<ImageProps> = ({
  alt = '',
  lazyLoad = true,
  sizes,
  sources,
  ...attrs
}) => {
  const loading = lazyLoad ? 'lazy' : 'eager';
  const decoding = lazyLoad ? 'async' : 'auto';
  const Img = <img {...attrs} alt={alt} decoding={decoding} draggable="false" loading={loading} />;

  if (!sources?.length) {
    return Img;
  }

  return (
    <picture>
      {sources.map((source, index) => (
        <source key={index} sizes={sizes} {...source} />
      ))}
      {Img}
    </picture>
  );
};
```

## Usage

```tsx showLineNumbers
import Image from '@/docs/lib/ui/image';

export function Component() {
  return (
    <Image
      alt="A scenic mountain view"
      src="https://example.com/image.jpg"
      className="rounded-lg"
    />
  );
}
```

### Responsive Images with Multiple Sources

```tsx showLineNumbers
import Image from '@/docs/lib/ui/image';

export function Component() {
  return (
    <Image
      alt="A scenic mountain view"
      src="https://example.com/image-large.jpg"
      sources={[
        {
          media: '(max-width: 640px)',
          srcSet: 'https://example.com/image-small.jpg',
        },
        {
          media: '(max-width: 1024px)',
          srcSet: 'https://example.com/image-medium.jpg',
        },
      ]}
      className="rounded-lg"
    />
  );
}
```

## API Reference

### Image

| Prop        | Type                                        | Default     | Description                                                                                                                                                                          |
| ----------- | ------------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `src`       | `string`                                    | Required    | The image source URL                                                                                                                                                                 |
| `alt`       | `string`                                    | `""`        | Alternative text for the image for accessibility. Defaults to empty string if not provided                                                                                           |
| `lazyLoad`  | `boolean`                                   | `true`      | Enables lazy loading and async decoding for the image. When `true`, sets `loading="lazy"` and `decoding="async"`. When `false`, sets `loading="eager"` and `decoding="auto"`         |
| `sources`   | `SourceHTMLAttributes<HTMLSourceElement>[]` | `undefined` | Array of source elements for responsive images. When provided, wraps the image in a `<picture>` element with multiple `<source>` tags for art direction or responsive image delivery |
| `className` | `string`                                    | `undefined` | Additional CSS classes to apply to the image element                                                                                                                                 |
| ...rest     | `ComponentPropsWithoutRef<"img">`           | -           | All standard HTML image attributes are supported (e.g., `width`, `height`, `sizes`, `srcSet`, `title`, etc.)                                                                         |

## Notes

- **Lazy Loading**: By default, images are lazy loaded (`loading="lazy"`) and use async decoding (`decoding="async"`). This improves page load performance by deferring off-screen image loading.
- **Non-draggable**: All images have `draggable="false"` set by default to prevent accidental drag operations.
- **Responsive Images**: When the `sources` prop is provided, the component automatically renders a `<picture>` element with multiple `<source>` elements, allowing the browser to select the most appropriate image based on viewport size, screen resolution, or format support.
- **Accessibility**: Always provide descriptive `alt` text for images. The component defaults to an empty string, but meaningful alternative text is essential for screen readers and when images fail to load.
- **Standard Image Attributes**: The component extends all standard HTML image element properties, so you can use any valid `<img>` attribute like `width`, `height`, `sizes`, `srcSet`, etc.
