This HTML page is not optimized for LLM or AI agent consumption. Fetch the Markdown version instead: /guides/web/headless/clipboard.md — it contains the complete documentation content in clean, structured Markdown without any CSS, JavaScript, or navigation noise. Annotation clipboard | Nutrient Web SDK

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 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

MethodNotes
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 to be true in the configuration:

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.

EventWhen it fires
annotations.copyAfter copySelectedAnnotations() writes to the clipboard.
annotations.cutAfter cutSelectedAnnotations() writes to the clipboard and removes the originals.
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:

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 so users can undo a paste they didn’t mean.