---
title: "Image (3.x)"
description: "Clover 3.x (@samvera/clover-iiif), the earlier version, documented for reference."
url: https://clover.iiif.library.northwestern.edu/docs/deprecated-versions/image
version: "3.x, the earlier version, superseded by Clover 4"
---

> This page documents **Clover 3.x**, `@samvera/clover-iiif`, the earlier version of Clover, kept here for reference. These docs lead with Clover 4: [Get started](https://clover.iiif.library.northwestern.edu/docs).

# Image

A UI component that renders a *pan and deep-zoom* Image viewer using [OpenSeadragon](https://openseadragon.github.io/).

[Image ↗](https://iiif.io/api/image/3.0)

## Features

Provide a IIIF Annotation body with the `type` of `Image` and the component:

- Renders a single [OpenSeadragon](https://openseadragon.github.io/) instance.
- Returns OpenSeadragon’s `Viewer` instance for programmatic control.
- Provides configuration options for OpenSeadragon’s `Viewer` instance.

## Installation

### npm

```shell
  npm install @samvera/clover-iiif
```

### yarn

```shell
  yarn add @samvera/clover-iiif
```

### pnpm

```shell
  pnpm install @samvera/clover-iiif
```

## Usage

### React

Add the `Image` component to your `jsx` or `tsx` code.

```jsx
import Image from "@samvera/clover-iiif/image";
```

#### Using `src` and `isTiledImage` props

For **Tiled Images**, render `Image` with a `src` attribute of the IIIF Image service `id`. The `isTiledImage` prop is optional and defaults to `false`.

### Code

```jsx
<div style={{ height: "400px" }}>
  <CloverImage
    src="https://iiif.dc.library.northwestern.edu/iiif/2/6ca016c5-de7f-4373-ae8f-7047fecf6ace"
    isTiledImage={true}
    label="#54, Bath. 15 Dibre 1806, p. 1 recto"
  />
</div>
```

For **Simple Images**, render `Image` with a `src` attribute of the image, ex: `https://example.org/image.jpg`. The `isTiledImage` must be omitted or set to `false`.

### Code

```jsx
<div style={{ height: "400px" }}>
  <CloverImage
    src="https://iiif.dc.library.northwestern.edu/iiif/2/6ca016c5-de7f-4373-ae8f-7047fecf6ace/full/1000,/0/default.jpg"
    label="#54, Bath. 15 Dibre 1806, p. 1 recto"
  />
</div>
```

#### Using the IIIF annotation `body`

When using the IIIF annotation `body` from IIIF Manifest, the `Image` component will render the image based on the IIIF Image service `id` and other properties.

### Code

```jsx
<div style={{ height: "400px" }}>
  <CloverImage
    body={{
      id: "https://iiif.dc.library.northwestern.edu/iiif/2/6ca016c5-de7f-4373-ae8f-7047fecf6ace/full/600,/0/default.jpg",
      type: "Image",
      format: "image/tiff",
      height: 5709,
      width: 8949,
      service: [
        {
          "@id":
            "https://iiif.dc.library.northwestern.edu/iiif/2/6ca016c5-de7f-4373-ae8f-7047fecf6ace",
          "@type": "ImageService2",
          profile: "http://iiif.io/api/image/2/level2.json",
        },
      ],
    }}
    label="#54, Bath. 15 Dibre 1806, p. 1 recto"
  />
</div>
```

### Vanilla JavaScript

The Viewer can also be implemented in Vanilla Javascript by use of a web component. This web component example sources a registered `<clover-viewer>` web component.

The script loads ES modules asynchronously. If self-hosting, copy the entire `dist/web-components/` directory, including `index.mjs` and its adjacent chunks. Serve `.mjs` files with a JavaScript MIME type and enable CORS for cross-origin hosting. Wait for `customElements.whenDefined("clover-image")` before using the element’s API immediately after loading the script.

### Code

```html
<html>
  <head>
    <title>Clover IIIF - Image - Web Component</title>
    <meta charset="UTF-8" />
  </head>
  <body>
    <script src="https://www.unpkg.com/@samvera/clover-iiif@latest/dist/web-components/index.umd.js"></script>
 
    <div style="height: 400px;">
        <clover-image
          src="https://iiif.dc.library.northwestern.edu/iiif/2/7192086f-fbe3-4939-b58a-6a63cddea42f"
          is-tiled-image="true"
          aria-label="A IIIF Image"
        />
    </div>
  </body>
</html>
```

### Next.js

Implementation with Next.js requires a [dynamic import](https://nextjs.org/docs/advanced-features/dynamic-import) utilizing `next/dynamic`. This is due to Next’s node compilation method creating issue with an `OpenSeadragon` (a dependency of Clover IIIF) assumption of a browser `document` object.

```jsx
import dynamic from "next/dynamic";
 
const Image = dynamic(
  () => import("@samvera/clover-iiif").then((Clover) => Clover.Image),
  {
    ssr: false,
  },
);
 
const MyCustomImage = () => {
  return (
    <Image src="https://ids.lib.harvard.edu/ids/iiif/18772291/full/full/0/default.jpg" />
  );
};
```

## API Reference

Note that while that `src` and `body` are both optional, at least one of them must be provided.

| Prop                    | Type                                                                                                                                 | Required |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | -------- |
| `body`                  | [`LabeledIIIFExternalWebResource`](https://iiif.io/api/presentation/3.0/#57-content-resources) or `LabeledIIIFExternalWebResource[]` | No       |
| `instanceId`            | `string`                                                                                                                             | No       |
| `label`                 | `string` or [IIIF Label](https://iiif.io/api/presentation/3.0/#label)                                                                | No       |
| `src`                   | `string` or `string[]`                                                                                                               | No       |
| `openSeadragonCallback` | function                                                                                                                             | No       |
| `openSeadragonConfig`   | OpenSeadragon.Options                                                                                                                | No       |

## OpenSeadragon

### OpenSeadragon Callback

The `Image` component uses [OpenSeadragon](https://openseadragon.github.io/) to render the image. The `openSeadragonCallback` prop provides a callback function that returns the OpenSeadragon `Viewer` instance. This can be used to programmatically control the viewer from the consuming application.

```jsx
import Image from "@samvera/clover-iiif/image";
 
const MyCustomImage = () => {
  export const handleOpenSeadragonCallback = (viewer) => {
    console.log("OpenSeadragon instance is ready");
    console.log(viewer);
  };
 
  return (
    <Image
      src="https://ids.lib.harvard.edu/ids/iiif/18772291/full/full/0/default.jpg"
      openSeadragonCallback={handleOpenSeadragonCallback}
    />
  );
};
```

### OpenSeadragon Configuration

The `openSeadragonConfig` prop provides a way to configure the OpenSeadragon `Viewer` instance. This prop accepts an object of [OpenSeadragon.Options](https://openseadragon.github.io/docs/OpenSeadragon.html#.Options).

```jsx
import Image from "@samvera/clover-iiif/image";
 
const MyCustomImage = () => {
  const openSeadragonConfig = {
    showNavigator: false,
    showRotationControl: true,
    // ... other OpenSeadragon options
  };
 
  return (
    <Image
      src="https://ids.lib.harvard.edu/ids/iiif/18772291/full/full/0/default.jpg"
      openSeadragonConfig={openSeadragonConfig}
    />
  );
};
```

Tiles are drawn with WebGL where the device supports it, which is OpenSeadragon’s own `auto` default. Each instance holds a WebGL context and browsers cap how many can exist at once, so a page with many images will log `Too many active WebGL contexts` and OpenSeadragon will recover on the canvas drawer. Pass `drawer: "canvas"` in `openSeadragonConfig` to pin it instead.

## Label and ARIA

The `label` prop is used to provide an accessible name for the OpenSeadragon. This is used as the `aria-label` attribute on the viewport element wrapping the OpenSeadragon canvas.

The label can be a `string` or a valid IIIF Presentation API 3.0 [label](https://iiif.io/api/presentation/3.0/#label).

```jsx
import Image from "@samvera/clover-iiif/image";
 
const MyCustomImage = () => {
  return (
    <Image
      src="https://ids.lib.harvard.edu/ids/iiif/18772291/full/full/0/default.jpg"
      label="Self-Portrait at Eleven Years Old"
    />
  );
};
```

```jsx
import Image from "@samvera/clover-iiif/image";
 
const MyCustomImage = () => {
  return (
    <Image
      src="https://ids.lib.harvard.edu/ids/iiif/18772291/full/full/0/default.jpg"
      label={{ en: ["Self-Portrait at Eleven Years Old"] }}
    />
  );
};
```

## Multiple Images

Both the `src` and `body` prop can be an array of image URLs or IIIF Image service IDs. This allows you to render multiple images in a single OpenSeadragon instance. If `body` is provided, the resources should be an array of [content resources](https://clover.iiif.library.northwestern.edu/docs/deprecated-versions/image#using-the-iiif-annotation-body).

```jsx
import Image from "@samvera/clover-iiif/image";
 
const MyCustomImage = () => {
  return (
    <Image
      src={[
        "https://iiif.dc.library.northwestern.edu/iiif/3/34906273-e661-4cf1-ae20-849c4d21d01c/full/1200,/0/default.jpg",
        "https://iiif.dc.library.northwestern.edu/iiif/3/cf9f7fc4-c242-4ca9-a77f-25daf355af92/full/1200,/0/default.jpg",
      ]}
      label="Michel Kovatchevitch correspondence, postcard"
    />
  );
};
```

## Annotations

The `annotations` prop is used to provide a list of web annotations to be rendered on the image. The `annotations` prop accepts an array of objects, each containing an `annotation` and a `targetIndex`. The `annotation` object should contain the IIIF annotation data, and the `targetIndex` should be the index of the target canvas in the `src` array, or `0` if the `src` is a single image.

```jsx
import Image from "@samvera/clover-iiif/image";
 
const MyAnnotatedImage = () => {
  return (
    <Image
      src={[
        "https://iiif.dc.library.northwestern.edu/iiif/3/f7409acd-e3f9-496a-b733-81f46d4ffa4f/full/max/0/default.jpg",
      ]}
      label="Patten Gymnasium, Northwestern University, Evanston, Ill."
      annotations={[
        {
          annotation: {
            id: "https://iiif.dc.library.northwestern.edu/iiif/3/f7409acd-e3f9-496a-b733-81f46d4ffa4f/annotation/0",
            type: "Annotation",
            motivation: ["tagging"],
            body: [
              {
                id: "https://iiif.dc.library.northwestern.edu/iiif/3/f7409acd-e3f9-496a-b733-81f46d4ffa4f/annotation/0/body/0",
                type: "TextualBody",
                value: "1935 Ford Coupe",
                language: "en",
              },
            ],
            target: {
              type: "SpecificResource",
              source: {
                id: "https://iiif.dc.library.northwestern.edu/iiif/3/f7409acd-e3f9-496a-b733-81f46d4ffa4f/full/max/0/default.jpg",
                type: "Canvas",
              },
              selector: {
                type: "FragmentSelector",
                value: "xywh=1000,1850,1200,600",
              },
            },
          },
          targetIndex: 0,
        },
        {
          annotation: {
            id: "https://iiif.dc.library.northwestern.edu/iiif/3/f7409acd-e3f9-496a-b733-81f46d4ffa4f/annotation/1",
            type: "Annotation",
            motivation: ["tagging"],
            body: [
              {
                id: "https://iiif.dc.library.northwestern.edu/iiif/3/f7409acd-e3f9-496a-b733-81f46d4ffa4f/annotation/1/body/0",
                type: "TextualBody",
                value: "1934 Packard Sedan",
                language: "en",
              },
            ],
            target: {
              type: "SpecificResource",
              source: {
                id: "https://iiif.dc.library.northwestern.edu/iiif/3/f7409acd-e3f9-496a-b733-81f46d4ffa4f/full/max/0/default.jpg",
                type: "Canvas",
              },
              selector: {
                type: "FragmentSelector",
                value: "xywh=2300,1750,1550,800",
              },
            },
          },
          targetIndex: 0,
        },
      ]}
    />
  );
};
```

In this example, two annotations are provided targeting the `src` image, one for a **1935 Ford Coupe** at coordinates `xywh=1000,1850,1200,600` and another for a **1934 Packard Sedan** at coordinates `xywh=2300,1750,1550,800`.

## Instance ID

The `instanceId` prop is used to provide an identifier defined from the consuming application for the OpenSeadragon instance. This is used as the `id` attribute on the viewport element wrapping the OpenSeadragon canvas. `instanceId` is optional and by default the `Image` component will generate a unique identifier.

```jsx
import Image from "@samvera/clover-iiif/image";
 
const MyCustomImage = () => {
  const instanceId = "my-defined-instance-id";
 
  const handleOpenSeadragonCallback = (viewer) => {
    console.log(viewer?.id);
    // openseadragon-my-defined-instance-id
  };
 
  return (
    <Image
      src="https://ids.lib.harvard.edu/ids/iiif/18772291/full/full/0/default.jpg"
      instanceId={instanceId}
      openSeadragonCallback={handleOpenSeadragonCallback}
    />
  );
};
```
