---
title: "Technical overview"
description: "How Clover's package works, in React and as web components side by side: its entry points, the Viewer, events, languages, parts, layouts, parts of your own, types, what each loads, styles, and coming from Clover 3.x."
url: https://clover.iiif.library.northwestern.edu/docs/technical
version: "4"
---

# Technical overview

How the package works, in React and as web components: the same parts, read the same way, in either. The code switch shows yours.

## Entry points

| Import                                | What it is                                                                                                                                                                  |
| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `@nulib/clover`                       | The [Viewer](https://clover.iiif.library.northwestern.edu/docs/viewer) (the default export), and every part, hook and helper (named).                                       |
| `@nulib/clover/templates`             | The [templates](https://clover.iiif.library.northwestern.edu/docs/viewer#templates): `Default`, `Document` and `Gallery`.                                                   |
| `@nulib/clover/map`                   | [`Map` (web components: `<clover-map>`)](https://clover.iiif.library.northwestern.edu/docs/map), for navPlace and georeferenced images. The Viewer adds its Map tab itself. |
| `@nulib/clover/three`                 | `registerThreeEngine`, to draw a [Scene](https://clover.iiif.library.northwestern.edu/docs/scene) with three.js, which you install.                                         |
| `@nulib/clover/web-components`        | `<clover-viewer>`, and [every part as an element](https://clover.iiif.library.northwestern.edu/docs/technical#parts), for a page without React.                             |
| `@nulib/clover/web-components/viewer` | `<clover-viewer>` alone, built whole, for a page that shows a Viewer and nothing else of Clover’s.                                                                          |
| `@nulib/clover/web-components/three`  | three.js for the elements’ [Scene](https://clover.iiif.library.northwestern.edu/docs/scene), bundled.                                                                       |
| `@nulib/clover/styles.css`            | Every part’s styles, and the `Default` template’s.                                                                                                                          |
| `@nulib/clover/templates.css`         | The other templates’ styles.                                                                                                                                                |

The package is ES modules only.

**React**

React 18 and 19 are supported. Import the parts from `@nulib/clover`, by name or as `Clover`, and your bundler keeps only those you use.

**Web components**

The elements are built on their own, with [Preact](https://preactjs.com/) standing in for React, and carry Clover’s stylesheet. `index.umd.js` is a classic script that loads the elements’ module from beside itself, so it works from any CDN path. On a page with modules, load `web-components/index.mjs` with `<script type="module">` instead.

```html
<script src="https://cdn.jsdelivr.net/npm/@nulib/clover/dist/web-components/index.umd.js"></script>
```

A page that shows a Viewer and nothing else of Clover’s can load the Viewer’s own entry, built whole: `web-components/viewer/index.umd.js` (or `@nulib/clover/web-components/viewer` in a bundler) loads 101 kB to first view, where the one for every element loads 121 kB for the same page. Load one entry on a page, not both: each brings its own copy of Clover.

If you serve Clover’s files from your own server, copy the whole `dist/web-components` folder, not `viewer/` alone: the Viewer’s entry loads what the other entry has too (the map, streaming video, the languages) from the folder above its own.

## The Viewer

**React**

`Viewer` draws its `template`, `Default` unless you pass another from `@nulib/clover/templates`, and hands every other prop to it. `iiifContent` takes a URL, a content state, or a IIIF resource as an object. Every prop is in the Viewer’s [API reference](https://clover.iiif.library.northwestern.edu/docs/viewer#api-reference).

**Web components**

`<clover-viewer>` shows the Viewer in any of its [templates](https://clover.iiif.library.northwestern.edu/docs/viewer#templates): Default unless `template` names another, which loads the first time one is shown, its styles with it. Every attribute is in the Viewer’s [API reference](https://clover.iiif.library.northwestern.edu/docs/viewer#api-reference).

```html
<clover-viewer
  template="document"
  iiif-content="https://iiif.io/api/cookbook/recipe/0024-book-4-toc/manifest.json"
></clover-viewer>
```

A template takes its own attributes and ignores another’s: `size` does nothing in Default. `false` is read in any case. An `items` value not in the list shows the slider, with a warning in the console. With `header="false"` there is no title, and the panel’s sections take `heading-level` themselves.

The `iiifContent` property takes a IIIF object as well, which an attribute cannot carry, set before the element’s script has loaded or after:

```js
document.querySelector("clover-viewer").iiifContent = manifestJson;
```

## Events

What React hands a callback, an element sends as an event: `clover-` and what happened, bubbling, so a page can listen for it anywhere above the element. Its `detail` holds what the callback is given.

| React prop                                                             | Event                         | `detail`                                      |
| ---------------------------------------------------------------------- | ----------------------------- | --------------------------------------------- |
| `onCanvasChange` (web components: `clover-canvas-change`)              | `clover-canvas-change`        | `{ canvasId }`                                |
| `onManifestChange` (web components: `clover-manifest-change`)          | `clover-manifest-change`      | `{ manifestId }`, in a Collection             |
| `onStatusChange` (web components: `clover-status-change`)              | `clover-status-change`        | `{ status, error }`, as it loads              |
| `onContentStateChange` (web components: `clover-content-state-change`) | `clover-content-state-change` | `{ json, encoded }`, where the reader settles |

**Web components**

```js
viewer.addEventListener("clover-canvas-change", (event) => {
  console.log(event.detail.canvasId);
});
```

`<clover-root>` sends the same events as `<clover-viewer>`; `<clover-items>` and `<clover-map>` send `clover-select` when an item or a place is chosen (cancel it, with `preventDefault`, to keep a link from being followed), `<clover-collection-select>` sends `clover-change`, and `<clover-root>`, `<clover-body>` and `<clover-canvas>` send `clover-ready` ([parts of your own](https://clover.iiif.library.northwestern.edu/docs/technical#parts-of-your-own)).

## Languages

Clover’s own words follow the page’s `<html lang>`, then the reader’s browser, in either. `initCloverI18n` sets their language, or adds strings, for every Clover part on the page; see [i18n](https://clover.iiif.library.northwestern.edu/docs/i18n).

**React**

```jsx
import { initCloverI18n } from "@nulib/clover";
 
initCloverI18n({ lng: document.documentElement.lang });
```

**Web components**

The elements carry their own copy of Clover’s translator, so a page calls it through them: from the module, or from any element’s class in a classic script.

```js
// With modules.
import { initCloverI18n } from ".../web-components/index.mjs";
initCloverI18n({ lng: document.documentElement.lang });
 
// From a classic script, once the element is defined.
customElements.get("clover-viewer").initCloverI18n({ lng: "fr" });
```

Where that language is not the page’s, Clover marks each of its own words with `lang`; see [Languages](https://clover.iiif.library.northwestern.edu/docs/composing#languages).

## Parts

**React**

Every part is a component, read inside a `Root`, among your own markup. Each has its page under Components, and [Composing](https://clover.iiif.library.northwestern.edu/docs/composing#parts) lists them all.

**Web components**

The parts compose in HTML inside a `<clover-root>`, as they do in JSX inside a `Root`. Each draws its part into itself, wherever the page puts it in the root, and the page’s own markup between them stays as written.

```html
<clover-root
  iiif-content="https://iiif.io/api/cookbook/recipe/0009-book-1/manifest.json"
>
  <clover-label as="h2"></clover-label>
  <clover-body style="height: 60vh"></clover-body>
  <p>Now showing <clover-label of="canvas"></clover-label>.</p>
  <clover-previous></clover-previous>
  <clover-position></clover-position>
  <clover-next></clover-next>
  <clover-summary></clover-summary>
  <clover-metadata></clover-metadata>
</clover-root>
```

| Elements                                                                                                                                                                                                                             | What they draw                                                                                                             | Attributes                                                                                                                                                                                               |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `<clover-root>`                                                                                                                                                                                                                      | Nothing of its own: it loads what it is given, and its parts read where the reader is.                                     | `iiif-content` (or the `iiifContent` property), `canvas-id` and `manifest-id` (where it opens; changed later, they move the reader), `language`, `search-query`, `annotations`.                          |
| `<clover-body>`                                                                                                                                                                                                                      | The view, in a box as tall as `--clover-body-height` (60vh) or its own `style`; a `<button>` in it is one of its controls. | `controls` and `navigator` (`false` turns one off), `placeholder`, `animate-annotations`; [parts of your own](https://clover.iiif.library.northwestern.edu/docs/technical#parts-of-your-own).            |
| `<clover-canvas>`                                                                                                                                                                                                                    | Clover’s renderer for images, video and sound: alone, what it is given; in a root, its view.                               | `iiif-content`, `src` and `tiled`, `controls`, `navigator`, and [more](https://clover.iiif.library.northwestern.edu/docs/technical#alone).                                                               |
| `<clover-items>`                                                                                                                                                                                                                     | Thumbnails of the views, or of the Collection’s members.                                                                   | `layout` (`slider`, `list`, `grid` or `pager`), `of`, `navigation`, `thumbnail-size`; alone, `iiif-content`, `header`, `heading-level`.                                                                  |
| `<clover-previous>`, `<clover-position>`, `<clover-next>`                                                                                                                                                                            | Stepping through the views, and where the reader is.                                                                       | `of` (`views` or `members`).                                                                                                                                                                             |
| `<clover-status>`                                                                                                                                                                                                                    | What the root is doing: loading, or why it failed.                                                                         | `loading="false"`, where the Body shows its own.                                                                                                                                                         |
| `<clover-label>`, `<clover-thumbnail>`, `<clover-summary>`, `<clover-metadata>`, `<clover-required-statement>`, `<clover-rights>`, `<clover-homepage>`, `<clover-see-also>`, `<clover-rendering>`, `<clover-part-of>`, `<clover-id>` | One IIIF property each, of the Manifest or the Canvas in view.                                                             | `of` (`manifest` or `canvas`); `value`, its own as text, a URL or JSON, which alone, outside a root, it shows; `as` on a label (a heading, `h1` to `h6`) and a summary; `size` and `alt` on a thumbnail. |
| `<clover-value>`                                                                                                                                                                                                                     | Any language map, as text, HTML or Markdown.                                                                               | `value`, `format`, `heading-level`, `as`.                                                                                                                                                                |
| `<clover-about>`, `<clover-annotations>`, `<clover-collection>`, `<clover-collection-select>`, `<clover-contents>`, `<clover-search>`, `<clover-transcript>`, `<clover-download>`                                                    | The information panel’s sections, each on its own.                                                                         | `heading-level` (one under the heading they sit beneath), and each its own.                                                                                                                              |
| `<clover-map>`                                                                                                                                                                                                                       | The root’s places and georeferenced images; alone, those of its `iiif-content`.                                            | `overlay`, `overlay-opacity`, `style-url`, `scroll-zoom`.                                                                                                                                                |
| `<clover-panel>`, `<clover-tab>`                                                                                                                                                                                                     | The information panel, in tabs or stacked boxes: the sections Clover has data for, or `<clover-tab>`s of your own.         | `layout`, `value`, `heading-level`, `closable`; a tab’s `value` and `label` (or a `slot="label"` child).                                                                                                 |
| `<clover-panel-toggle>`                                                                                                                                                                                                              | A button that shows and hides the panel, or anything, by its id; in a `<clover-body>`, one of the Body’s controls.         | `controls`.                                                                                                                                                                                              |
| `<clover-split>`, `<clover-split-pane>`, `<clover-split-handle>`                                                                                                                                                                     | Panes side by side, and the bars between them, which the reader drags, clicks or moves by keyboard.                        | The split’s `storage-key`; a pane’s `size`, `min`, `max` and `name`.                                                                                                                                     |
| `<clover-tip>`                                                                                                                                                                                                                       | Clover’s popover, in a button of yours: its label and its key, as Clover’s controls show theirs.                           | `label`, `keys`, `glyph`, `lang`.                                                                                                                                                                        |

Every attribute, property and event is in the [manifest](https://clover.iiif.library.northwestern.edu/docs/technical#types). A part of a root draws nothing outside one, and says so in the console. Give an element no `aria-label` or `role`: it is a box no reader is told of, and Clover names what it draws itself; a landmark of the page’s own around an element names it otherwise. The one exception is a Split’s handle, which is the separator itself: name it with `aria-label` where “Resize panels” is not the right word.

## Layouts

**React**

`Split` lays panes side by side, `Panel` holds the information panel’s sections or `Tab`s of your own, and `PanelToggle` shows and hides it: see [Panes side by side](https://clover.iiif.library.northwestern.edu/docs/composing#panes-side-by-side) and [Panel](https://clover.iiif.library.northwestern.edu/docs/panel).

**Web components**

A layout as the Default template’s, written in HTML: the Body with the panel’s toggle among its controls, a bar the reader can move, and the information panel beside it, with tabs of your own.

```html
<clover-root
  iiif-content="https://iiif.io/api/cookbook/recipe/0024-book-4-toc/manifest.json"
>
  <clover-split storage-key="my-layout" style="height: 80vh">
    <clover-split-pane min="16rem">
      <clover-label as="h2"></clover-label>
      <clover-body style="height: 60vh">
        <clover-panel-toggle controls="panel-pane"></clover-panel-toggle>
      </clover-body>
      <clover-items></clover-items>
    </clover-split-pane>
    <clover-split-handle></clover-split-handle>
    <clover-split-pane id="panel-pane" size="24rem" min="14rem">
      <clover-panel>
        <clover-tab value="about" label="About">
          <clover-about heading-level="3"></clover-about>
        </clover-tab>
        <clover-tab value="notes">
          <span slot="label">Notes <em>(2)</em></span>
          <p>Our own notes on this book.</p>
        </clover-tab>
      </clover-panel>
    </clover-split-pane>
  </clover-split>
</clover-root>
```

- **The panel** has the sections Clover has data for, or one tab for each `<clover-tab>` in it, in their order. A tab’s content stays where you wrote it until its section first opens, and then moves there. Its label is its `label`, or a copy of its `slot="label"` child, for markup. `value` is the tab it opens on, and changing it shows another; the reader’s choice sends `clover-value-change`. With `closable`, it has a close button, which sends `clover-close` (cancel it to keep the panel shown) and hides what its toggle shows.
- **The toggle** shows its target while the target is not `hidden`, so write `hidden` on the panel to start it shut, and hide or show it yourself whenever you like: the toggle follows. Each press sends `clover-open-change`; cancel it to leave the panel as it is.
- **The Split’s** elements are the panes and the bars themselves, as `Split` lays them out in React: one pane beside each handle has a `size`, and the other takes what is left. A handle beside a pane you hide is hidden with it.
- **Slots.** `<clover-status>` shows your own words while the root loads (`slot="loading"`) and if it fails (`slot="error"`), as copies, so give them no ids.
- **Functions.** `renderValue` on `<clover-metadata>`, `renderEntry` on `<clover-annotations>` and `renderItem` on `<clover-items>` are properties that take a function returning a node or text: Clover shows it where it would draw its own.

## Alone

**React**

Three parts need no `Root`: [`Canvas`](https://clover.iiif.library.northwestern.edu/docs/canvas) draws what it is given, [`Items`](https://clover.iiif.library.northwestern.edu/docs/items) lists a Collection’s members or a Manifest’s views, and [`Map`](https://clover.iiif.library.northwestern.edu/docs/map) maps the places of what it is given. Each of their pages shows it alone.

**Web components**

Three elements need no root. `<clover-canvas>` draws what it is given: a IIIF resource by URL (a Manifest gives its first Canvas), an image by `src` (with `tiled`, a IIIF Image service), or Canvases as its `canvases` property. `<clover-items>` lists a Collection’s members, or a Manifest’s views, as links. `<clover-map>` maps the places of what it is given.

```html
<clover-canvas
  iiif-content="https://iiif.io/api/cookbook/recipe/0005-image-service/manifest.json"
  style="height: 60vh"
></clover-canvas>
 
<clover-items
  iiif-content="https://iiif.io/api/cookbook/recipe/0032-collection/collection.json"
  heading-level="3"
></clover-items>
 
<clover-map
  iiif-content="https://iiif.io/api/cookbook/recipe/0240-navPlace-on-canvases/manifest.json"
></clover-map>
```

`<clover-canvas>` takes `controls` and `navigator` as `<clover-body>` does, `label` (the name of an image given by `src`), `placeholder` (`false` opens a Canvas past its placeholder), `viewing-direction` (how a spread is laid out) and `animate-annotations`. It sends `clover-annotation-select` and `clover-annotation-active` (`{ id }`), `clover-caption-change` (`{ caption }`) and `clover-ended`. Inside a `<clover-root>`, given nothing, it shows the root’s view; place [`<clover-body>`](https://clover.iiif.library.northwestern.edu/docs/canvas#canvas-or-body) there instead, which adds a height and the loading mark.

## Parts of your own

**React**

Hooks read from the nearest `Root`, and each re-renders only when what it reads changes: `useNavigation()`, `useVisibleCanvases()`, `useActiveCanvas()` and the rest, in [Parts of your own](https://clover.iiif.library.northwestern.edu/docs/composing#parts-of-your-own). `Canvas` and `Body` hand their handle to `onReady`; `renderers` on a `Root`, `Body` or `Viewer` draws views of your own ([Renderers of your own](https://clover.iiif.library.northwestern.edu/docs/composing#renderers-of-your-own)); and `controlButtons` puts buttons of yours in place of the Body’s controls ([Controls of your own](https://clover.iiif.library.northwestern.edu/docs/composing#controls-of-your-own)).

**Web components**

A script of the page’s reads a root as a React part reads one with Clover’s hooks. Once the root has loaded, `root.clover` is its Clover, and `clover-ready` says so. Each hook is a method of the same name (`useNavigation()` is `navigation()`, `useVisibleCanvases()` is `visibleCanvases()`), with the table of contents (`contents()`, as `tableOfContents` gives React’s), `state` and `subscribe`, the actions (`next()`, `goTo(id)`, `search(query)`…), the channels (`viewport`, `media`…), and `localize`, `t` and `langOf` for the root’s language.

```html
<clover-root
  id="book"
  iiif-content="https://iiif.io/api/cookbook/recipe/0009-book-1/manifest.json"
>
  <clover-body></clover-body>
  <p id="where"></p>
  <button type="button" id="next">Next view</button>
</clover-root>
 
<script type="module">
  const root = document.getElementById("book");
  const where = document.getElementById("where");
  const show = () => {
    const { position, total } = root.clover.navigation();
    where.textContent = `View ${position + 1} of ${total}`;
  };
  root.addEventListener("clover-ready", () => {
    show();
    root.clover.subscribe(show);
  });
  document
    .getElementById("next")
    .addEventListener("click", () => root.clover?.next());
</script>
```

- **The Canvas’s handle.** `<clover-canvas>` and `<clover-body>` keep it as `handle` once their view is laid out, as `onReady` hands it to a React host, and send `clover-ready`: `body.handle.zoomBy(2)`, `body.handle.home()`. A `clover-ready` is the element’s own, and does not bubble, as `load` does not.

- **Renderers.** `renderers` on a `<clover-root>`, `<clover-body>` or `<clover-viewer>` draws views of your own, as React’s do. Each claims views by `canvasId`, `format` or `match`, and its `render(container, view)` draws one into a box filling the Body and returns what undoes it. `view` holds the view’s Canvases, their painting bodies and the root’s `clover`, and the Body’s controls stay over it.

  ```js
  root.renderers = [
    {
      format: ["model/gltf-binary"],
      render(container, { bodies }) {
        const model = showModel(container, bodies[0].id);
        return () => model.dispose();
      },
    },
  ];
  ```

- **Controls of your own.** `controlButtons` on a `<clover-body>` or `<clover-canvas>` replaces any of its controls with a button you make: a function given the control’s `name`, `label` and Clover’s `icon`, returning the button. Clover keeps it named, keyed and in its state, presses the control with it, and adds its popover. A `<button>` you write in a `<clover-body>` is one of its controls, after Clover’s, as a React host’s children are. `class="clover-canvas-button"` gives it Clover’s look, and a `<clover-tip>` in it the popover Clover’s controls show (`<Clover.Tip>` in React).

  ```html
  <clover-body>
    <button type="button" class="clover-canvas-button" aria-label="Share">
      <svg aria-hidden="true">…</svg>
      <clover-tip label="Share"></clover-tip>
    </button>
  </clover-body>
  ```

## Helpers

A few of the functions Clover’s parts are built with, for parts of your own and the page around Clover, from `@nulib/clover`’s main entry. With React or with the elements, a bundler reaches them there; the elements’ CDN scripts do not carry them.

| Helper                                                      | What it does                                                                                                                                                                                                              |
| ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `readAs(format, value)`                                     | How a text is read: `"html"`, `"markdown"` or `"plain"`, by its `format`’s media type, or, with none, by IIIF’s rule (HTML only from a first `<` to a last `>`).                                                          |
| `toPlainText(html)`                                         | IIIF HTML as plain text, its tags dropped and the common entities decoded, for where markup cannot go: an `alt`, an `aria-label`.                                                                                         |
| `thumbnailSource(resource)`                                 | Where a resource’s thumbnail comes from: its `thumbnail`, else the first image it paints, its placeholder’s or its accompanying Canvas’s. `null` if it has nothing to show.                                               |
| `regionSource(canvas, { x, y, w, h })`                      | A small picture of a region of a Canvas, in the Canvas’s own coordinates (an annotation’s `xywh`), cut by the image server. `null` where no image with a service is painted there.                                        |
| `resolveThumbnail(source, size, request)`                   | Either source as a URL about `size` pixels on its longer side (200 by default), asked of the image service as its own `info.json` allows: never larger than the image, and a level 0 server’s listed sizes only.          |
| `buildContentState({ manifestId, canvasId, region, time })` | Where a reader is, as a content state: `{ json, encoded }`, the annotation and its base64url form for a link’s `iiif-content`. `encodeContentState(json)` encodes one of your own, `decodeContentState(value)` reads one. |

```js
import {
  buildContentState,
  resolveThumbnail,
  thumbnailSource,
} from "@nulib/clover";
 
const { encoded } = buildContentState({ manifestId, canvasId, time: 42 });
const link = `https://example.org/viewer?iiif-content=${encoded}`;
 
const picture = await resolveThumbnail(thumbnailSource(manifest), 400);
```

## Types

**React**

Each component’s props are exported beside it (`ViewerProps`, `RootProps`, `BodyProps`…), with the types its props and hooks use, from `@nulib/clover`.

**Web components**

The module’s types declare every element (`HTMLElementTagNameMap`) and every event, so `document.querySelector("clover-root")` is typed, and what a script reaches: `CloverRootApi`, `CloverCanvasHandle`, `CloverRenderer` and `CloverControlButtons`. Its [Custom Elements Manifest](https://github.com/webcomponents/custom-elements-manifest), `@nulib/clover/web-components/custom-elements.json` (the package’s `customElements`), gives each element’s attributes, properties and events to editors and tools.

## What it loads

**React**

Only the parts you import, as your bundler splits them. Showing an image, a page with the Viewer in its Default template loads 95 kB to first view, its styles included, and one with a `Canvas` alone 46 kB of script. React is your page’s own, and not counted. Each part’s page gives what it adds to a page with a `Root`.

**Web components**

The script is 5 kB gzipped: it defines every element and draws none. An element’s code loads the first time one is on the page, with Preact and the styles of what it draws, so a page loads only the elements it uses, and their styles, to first view: 121 kB with a `<clover-viewer>`, the Viewer in its Default template among it (3.x’s element loads 563 kB), 129 kB with one in Document, 87 kB for a `<clover-canvas>` alone, and 35 kB for a `<clover-root>` and its `<clover-label>`s, as the package’s build measures them.

Everything else waits until it is needed: video streaming (hls.js), the sanitizer, an animation’s player, and the map — MapLibre, its worker and its stylesheet load the first time a map is shown.

## Styles

**React**

Import `@nulib/clover/styles.css` once, and `templates.css` for a template other than Default. Their rules sit in `@layer clover`, so your own CSS wins; see [Styling](https://clover.iiif.library.northwestern.edu/docs/styling).

**Web components**

The element renders into its own children, with no shadow root, so the page’s CSS still reaches it, as 3.x’s does. Clover’s styles are added to the document once each, first in `<head>` and in the stylesheet’s order, so the page’s own rules win; see [Styling](https://clover.iiif.library.northwestern.edu/docs/styling).

## Coming from Clover 3.x

| Clover 3.x                                                                                               | Clover 4                                                                                                                          |
| -------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `Viewer` (web components: `<clover-viewer>`)                                                             | `Viewer` (web components: `<clover-viewer>`), in its `Default` template                                                           |
| `Slider`                                                                                                 | [`Items` (web components: `<clover-items>`)](https://clover.iiif.library.northwestern.edu/docs/items)                             |
| `Image`                                                                                                  | [`Canvas` (web components: `<clover-canvas>`)](https://clover.iiif.library.northwestern.edu/docs/canvas), Clover’s own renderer   |
| `Scroll`                                                                                                 | Not in Clover 4 yet; see [Scroll in 3.x](https://clover.iiif.library.northwestern.edu/docs/3.x/scroll)                            |
| `Map` (web components: `<clover-map>`)                                                                   | [`Map` (web components: `<clover-map>`)](https://clover.iiif.library.northwestern.edu/docs/map), on MapLibre                      |
| Primitives (`Label` (web components: `<clover-label>`), `Summary` (web components: `<clover-summary>`)…) | Parts of the same names, reading from the nearest `Root` (web components: `<clover-root>`)                                        |
| `options` (web components: `.options`)                                                                   | Props on the parts, and CSS custom properties                                                                                     |
| Information panel                                                                                        | [`Panel` (web components: `<clover-panel>`)](https://clover.iiif.library.northwestern.edu/docs/panel)                             |
| Information panel plugins                                                                                | `Clover.Tab` (web components: `<clover-tab>`), and hooks such as `useActiveCanvas` (web components: `root.clover.activeCanvas()`) |
| `customDisplays`                                                                                         | `renderers` (web components: `.renderers`)                                                                                        |

The [Clover 3.x](https://clover.iiif.library.northwestern.edu/docs/3.x) docs are kept beside these.
