Clipboard: write() method
Baseline 2024>
Newly available
Since June 2024, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.
Secure context: This feature is available only in secure contexts (HTTPS), in some or all supporting browsers.
The write() method of the Clipboard interface is used to write data such as images, text, and custom types, to the system clipboard.
The method takes as an argument an array of ClipboardItem instances, and returns a Promise that is fulfilled when the data is written.
Each ClipboardItem can contain one or more representations of an object that has been copied, allowing apps that read the data to pick the format they prefer.
This is more flexible than writeText(), which can only write text.
Syntax
write(data)
Parameters
data-
An array of
ClipboardItemobjects containing data to be written to the clipboard.
Return value
A Promise which is resolved when the data has been written to the clipboard.
Note that if the underlying OS does not support multiple native clipboard items on the system clipboard, then only the first ClipboardItem in the array is written.
The promise is rejected if the clipboard is unable to write to the clipboard.
Exceptions
NotAllowedErrorDOMException-
Thrown if writing to the clipboard is not allowed.
Description
Each item in the data array is a ClipboardItem that can contain one or more representations of the data being written, keyed by MIME type.
Providing multiple representations lets an app that later pastes the data pick the best format it understands.
Browsers commonly support writing text, HTML, and PNG image data, and may support web custom formats (see the Browser compatibility section of ClipboardItem).
Security considerations
Writing to the clipboard can only be done in a secure context.
Additional security requirements are covered in the Security consideration section of the API overview topic.
Examples
>Write text to the clipboard
This example function replaces the current contents of the clipboard with a specified string when a button is pressed.
Note that for this particular case, you could just as readily use Clipboard.writeText().
button.addEventListener("click", () => setClipboard("<empty clipboard>"));
async function setClipboard(text) {
const type = "text/plain";
const clipboardItemData = {
[type]: text,
};
const clipboardItem = new ClipboardItem(clipboardItemData);
await navigator.clipboard.write([clipboardItem]);
}
The setClipboard() function specifies a "text/plain" MIME type in the type constant, then specifies a clipboardItemData object with a single property — its key is the MIME type, and its value is the passed in text that we want to write to the clipboard. We then construct a new ClipboardItem object into which the clipboardItemData object is passed.
Finally, write() is called with await to write the data to the clipboard.
Write canvas contents to the clipboard
This example draws a blue rectangle to the canvas. You can click the rectangle to copy the content of the canvas into the clipboard as an image, and then select another element and paste in the content from the clipboard.
HTML
The HTML just defines our <canvas> element and the <div> element with id target where the canvas image will be pasted.
<canvas id="canvas" width="100" height="100"></canvas>
<div id="target">Paste here.</div>
const logElement = document.querySelector("#log");
function log(text) {
logElement.innerText = `${logElement.innerText}${text}\n`;
logElement.scrollTop = logElement.scrollHeight;
}
JavaScript
First we define an async function to copy a canvas to a blob.
This wraps the old callback-style HTMLCanvasElement.toBlob() method into the more intuitive Promise based function.
// Async/await method replacing toBlob() callback
async function getBlobFromCanvas(canvas) {
return new Promise((resolve, reject) => {
canvas.toBlob((blob) => {
if (blob) {
resolve(blob);
} else {
reject(new Error("Canvas toBlob failed"));
}
});
});
}
Next we set up our canvas and add an event listener for the click event.
When you click the blue rectangle, the canvas displaying the rectangle is copied into a blob, and then the blob is added to a ClipboardItem and then written to the clipboard.
const canvas = document.getElementById("canvas");
// Set up canvas
const ctx = canvas.getContext("2d");
ctx.fillStyle = "cornflowerblue";
ctx.fillRect(0, 0, 100, 100);
canvas.addEventListener("click", copyCanvasContentsToClipboard);
const target = document.getElementById("target");
async function copyCanvasContentsToClipboard() {
// Copy canvas to blob
try {
const blob = await getBlobFromCanvas(canvas);
// Create ClipboardItem with blob and its type, and add to an array
const data = [new ClipboardItem({ [blob.type]: blob })];
// Write the data to the clipboard
await navigator.clipboard.write(data);
log("Copied");
} catch (error) {
log(error);
}
}
Note that if you are fetching a less-common file type or a resource that you don't know the type in advance, you may want to use ClipboardItem.supports() to check if the file type is supported, and provide a good error message to the user in case it isn't.
We then define an event listener for paste events on then element where we want to display the clipboard contents as an image.
The FileReader API allows us to read the blob using the readAsDataUrl method and create an <img> element with the canvas contents:
target.addEventListener("paste", (event) => {
const items = (event.clipboardData || window.clipboardData).items;
const blob = items[0].getAsFile();
const reader = new FileReader();
reader.addEventListener("load", (event) => {
const img = new Image();
img.src = event.target.result;
target.appendChild(img);
});
reader.readAsDataURL(blob);
});
Result
The result is shown below.
First click on the blue square, and then select the text "Paste here" and use your OS-specific keyboard combinations to paste from the clipboard (such as Ctrl+V on Windows).
Writing a custom format to the clipboard
This example uses the same code as Reading and writing custom formats in the Clipboard API overview, but shows only the code that's specific to write().
For more detail see that example.
HTML
JavaScript
Here we define the custom media ("MIME") type that we will use in the following code.
We also use ClipboardItem.supports() to check whether that particular format is supported and log that to the output.
Note that this example works either way, we just won't be able to read (or write) the custom type.
const customType = "web text/x-mdn-inventory+json";
log(
ClipboardItem.supports(customType)
? `Custom format supported: ${customType}`
: `Custom format not supported by this browser: ${customType}`,
);
The following code builds the ClipboardItem when the copy button is pressed.
This creates representation for text/html and text/plain blobs, and adds the custom-format blob only when ClipboardItem.supports() confirms the browser accepts it.
There is nothing special about the blob for the custom format: the only difference is theweb prefix used for its key.
The text/html blob omits the SKU column stored in the custom format, and acts as a fall back when the content is pasted in apps and browsers that don't allow the format.
const sourceTable = document.querySelector("#source");
const copyButton = document.querySelector("#copy_custom");
async function copyInventory() {
const reducedTable = buildTable(
["Item", "Quantity"],
inventory.map((row) => [row.item, row.quantity]),
);
const html = reducedTable.outerHTML;
const text = inventory
.map((row) => `${row.item}\t${row.quantity}`)
.join("\n");
const data = {
"text/html": new Blob([html], { type: "text/html" }),
"text/plain": new Blob([text], { type: "text/plain" }),
};
if (ClipboardItem.supports(customType)) {
const json = JSON.stringify(inventory);
data[customType] = new Blob([json], { type: customType });
}
try {
await navigator.clipboard.write([new ClipboardItem(data)]);
log(`Copied ${Object.keys(data).length} format(s) to the clipboard.`);
} catch (error) {
log(`Copy failed: ${error.message}`);
}
}
copyButton.addEventListener("click", copyInventory);
document.addEventListener("copy", (event) => {
const selection = document.getSelection();
if (!sourceTable.contains(selection.anchorNode)) return;
event.preventDefault();
copyInventory();
});
Result
Click the "Copy" button, or select the table and copy it manually, to write the table to the clipboard as HTML, plain text, and (if supported) the custom format. Click each of the three "Paste" buttons to see what each representation was used for, or see Reading and writing custom formats in the Clipboard API overview for the full walkthrough. Click "Reload" to reset the example.
Note: If prompted, grant permission in order to copy and paste.
Specifications
| Specification |
|---|
| Clipboard API and events> # dom-clipboard-write> |