# Object Image (https://v2.s3.dimah.dev/docs/react/ui/components/object-image)

`ObjectImage` renders an `<img>` for a private object. It signs an inline URL
with [`useObjectUrl`](https://v2.s3.dimah.dev/docs/react/hooks/object-url), which refreshes the URL
before it expires and shares it with other images of the same object.

## Preview [#preview]

<DemoPreview name="object-image-demo.tsx">
  <ObjectImageDemo />
</DemoPreview>

## Install [#install]

Complete [UI Setup](https://v2.s3.dimah.dev/docs/react/ui) first: the stylesheet and one
`<Toaster />`. Then add this component:

<Tabs items={["npm package", "shadcn registry"]}>

<Tab value="npm package">

```tsx
import { ObjectImage } from "@dimah-s3/ui";
```

</Tab>

<Tab value="shadcn registry">

```npm
npx shadcn@latest add @dimah-s3/object-image
```

</Tab>

</Tabs>

---

## Usage [#usage]

```tsx
"use client";

import { ObjectImage } from "@dimah-s3/ui";

export function CoverImage({ coverKey }: { coverKey: string | null }) {
  return (
    <ObjectImage
      route="covers"
      objectKey={coverKey}
      alt="Album cover"
      className="size-40 rounded-md object-cover"
      fallback={<div className="bg-muted size-40 rounded-md" />}
    />
  );
}
```

`alt` is required. Pass `alt=""` when the image is decorative, such as next
to a name that already describes it. Other `<img>` props pass through.

## Fallback [#fallback]

`fallback` renders in place of the image while there is no key, while the URL
is being signed, when signing fails, and when the image fails to load. It
defaults to nothing. A failed image is not signed again; the next refresh
signs a new URL. Your `onError` still runs.

The route's server [download hooks](https://v2.s3.dimah.dev/docs/server/hooks/download) decide who
may read the object, as they do for any download.

---

## Props [#props]

```ts
import type { ObjectImageProps } from "@dimah-s3/ui";
```

<AutoTypeTable
  path="packages/ui/src/components/dimah-s3/preview/object-image.tsx"
  name="ObjectImageProps"
/>
