---
title: "Annotation clipboard | Nutrient Web SDK"
canonical_url: "https://www.nutrient.io/guides/web/headless/clipboard/"
md_url: "https://www.nutrient.io/guides/web/headless/clipboard.md"
last_updated: "2026-05-15T19:10:05.084Z"
description: "Copy, cut, paste, and duplicate any annotation type from your own UI using Nutrient Web SDK’s type-agnostic clipboard APIs."
---

# Annotation clipboard

Nutrient Web SDK exposes a type-agnostic annotation clipboard on the instance. The same four methods work for every annotation type (ink, text, markup, shape, link, redaction, stamp), so you can build a custom context menu, toolbar, or keyboard shortcut without writing per-type branching code.

Looking for the visual side of this? See the `annotations.actions` [slot](https://www.nutrient.io/guides/web/user-interface/ui-customization/supported-slots.md#annotations) for replacing the action UI that appears around a selected annotation. This page covers the programmatic path you’ll call from inside that custom UI.

## When to use this

The built-in keyboard shortcuts (Control-C/Command-C, Control-X/Command-X, Control-V/Command-V, Control-D/Command-D) cover the default user experience. Use the programmatic API when you want to:

- Trigger copy, cut, paste, or duplicate from your own UI — for example, a right-click context menu, a host-app toolbar, or a slot replacement.

- Trigger a clipboard action in response to an event the keyboard shortcuts don’t cover, such as a drop target or a remote command from a multiuser collaboration layer.

## API reference

| Method                                    | Notes                                                                      |
| ----------------------------------------- | -------------------------------------------------------------------------- |
| `instance.copySelectedAnnotations()`      | Copies the currently selected annotations to the SDK’s internal clipboard. |
| `instance.cutSelectedAnnotations()`       | Cuts the currently selected annotations (copy plus delete).                |
| `instance.pasteAnnotations()`             | Pastes the clipboard contents. Throws if the clipboard is empty.           |
| `instance.duplicateSelectedAnnotations()` | Duplicates the currently selected annotations in place.                    |

The clipboard is shared across all annotation types, so a copy of a `RectangleAnnotation` followed by a copy of an `InkAnnotation` overwrites the rectangle.

These methods require [`enableClipboardActions`](https://www.nutrient.io/api/web/NutrientViewer.Configuration.html#enableClipboardActions) to be `true` in the configuration:

```js

NutrientViewer.load({
  // Other options.
  enableClipboardActions: true
});

```

## Events

The SDK emits two events when a clipboard operation runs, regardless of whether it was triggered by the keyboard shortcut or by the programmatic API.

| Event              | When it fires                                                                       |
| ------------------ | ----------------------------------------------------------------------------------- |
| `annotations.copy` | After `copySelectedAnnotations()` writes to the clipboard.                          |
| `annotations.cut`  | After `cutSelectedAnnotations()` writes to the clipboard and removes the originals. |

```js

instance.addEventListener("annotations.copy", (event) => {
  console.log(`${event.annotations.size} annotation(s) copied.`);
});

```

## Example: A custom annotation context menu

This example wires the four clipboard methods to a host-app context menu that appears when the user right-clicks a selected annotation. The menu items are gated by selection state — copy, cut, and duplicate only show when there’s at least one annotation selected:

```js

const instance = await NutrientViewer.load({
  container: "#viewer",

  document: "contract.pdf",
  enableClipboardActions: true,
  enableHistory: true
});

const menu = document.getElementById("annotation-context-menu");

instance.contentDocument.addEventListener("contextmenu", (event) => {
  const selected = instance.getSelectedAnnotations();
  const hasSelection = selected && selected.size > 0;

  menu.innerHTML = "";

  if (hasSelection) {
    addItem("Copy", () => instance.copySelectedAnnotations());
    addItem("Cut", () => instance.cutSelectedAnnotations());
    addItem("Duplicate", () => instance.duplicateSelectedAnnotations());
  }

  addItem("Paste", () => instance.pasteAnnotations());

  menu.style.left = `${event.pageX}px`;
  menu.style.top = `${event.pageY}px`;
  menu.style.display = "block";
  event.preventDefault();
});

function addItem(label, handler) {
  const item = document.createElement("button");
  item.textContent = label;
  item.onclick = () => {
    handler();
    menu.style.display = "none";
  };
  menu.appendChild(item);
}

```

Also enable [`enableHistory`](https://www.nutrient.io/api/web/NutrientViewer.Configuration.html#enableHistory) so users can undo a paste they didn’t mean.

## Related

- [Cut, copy, paste, and duplicate annotations](https://www.nutrient.io/guides/web/annotations/create-edit-and-remove/cut-copy-duplicate.md) — The built-in keyboard-shortcut behavior.

- [Annotation customization](https://www.nutrient.io/guides/web/annotations/custom-rendered-annotations.md) — For replacing the rendered annotation chrome.
---

## Related pages

- [Headless callout annotations](/guides/web/headless/callout.md)
- [Headless color presets](/guides/web/headless/color-presets.md)
- [Headless image annotations](/guides/web/headless/image.md)
- [Headless](/guides/web/headless.md)
- [Headless ink annotations](/guides/web/headless/ink.md)
- [Headless stamp annotations](/guides/web/headless/stamp.md)
- [Headless link annotations](/guides/web/headless/link.md)
- [Headless note annotations](/guides/web/headless/note.md)
- [Redactions from text selection](/guides/web/headless/redactions-from-selection.md)
- [Programmatic notes panel](/guides/web/headless/notes-panel.md)
- [Headless text annotations](/guides/web/headless/text-annotations.md)
- [Headless shape annotations](/guides/web/headless/shape.md)
- [Headless text markup](/guides/web/headless/text-markup.md)

