JavaScriptBrowser APIs

navigator.clipboard

Asynchronous access to the system clipboard. The writeText() method copies text, and readText() reads it back from the clipboard.

Returns
A promise. For writeText() and write() it fulfills with undefined, for readText() with the clipboard’s string, and for read() with an array of ClipboardItem objects.
On this page

Example

#
JavaScript
const copyButton = document.querySelector('#copy')
const snippet = document.querySelector('#snippet')

copyButton.addEventListener('click', async () => {
  try {
    await navigator.clipboard.writeText(snippet.textContent)
    copyButton.textContent = 'Copied!'
    console.log('Copied:', snippet.textContent)
  } catch (error) {
    console.log('Could not copy:', error.name)
  }
})
Result
Copied: console.log('Welcome to CodeWorlds!')

The browser blocks the clipboard in the isolated frame the examples on this page run in, so the code doesn’t run in the preview. On a regular page with a #snippet code block, clicking the button copies its content, and the console shows the result above.

Definition and usage

#

navigator.clipboard is an object for working with the system clipboard. Most often you’ll use the writeText(text) method, which copies a string to the clipboard, e.g. after clicking a “Copy code” button. The readText() method reads text from the clipboard, and write() and read() also handle other data, such as images, wrapped in ClipboardItem objects.

All the methods are asynchronous and return promises, so use them with await or then(). The promise is rejected when the browser doesn’t allow the operation, so always handle errors, e.g. with a try...catch block.

The clipboard only works on pages opened over HTTPS (or from localhost), and browsers guard it against abuse. Writing requires the page to be active, and in some browsers also that the code runs in response to a user action, such as a click. Reading is protected more strictly: the browser may ask for permission or show a “Paste” button. Inside iframe frames, the parent page must also grant access.

The writeText() method has worked in all major browsers for years. readText(), read(), write(), and ClipboardItem objects have only been available everywhere since 2024, so it’s worth checking that they exist before using them.

Syntax

#
Syntax
navigator.clipboard.writeText(text)
navigator.clipboard.readText()
navigator.clipboard.write(items)
navigator.clipboard.read()

Parameters

#
  • text

    string

    The text to copy, in writeText().
  • items

    array of ClipboardItem

    The data to save in write(), e.g. an image or text in several formats.

More examples

#
Pasting a link from the clipboard
JavaScript
document.querySelector('#paste').addEventListener('click', async () => {
  try {
    const text = await navigator.clipboard.readText()
    document.querySelector('#project-link').value = text.trim()
    console.log('Pasted:', text.trim())
  } catch (error) {
    console.log('No access to the clipboard:', error.name)
  }
})
Result
Pasted: https://github.com/emma/calculator

When reading, the browser may ask for permission or show a “Paste” button. If the user refuses, the promise is rejected with a NotAllowedError, and the catch block runs.

Checking whether the clipboard is available
JavaScript
async function copyText(text) {
  if (!navigator.clipboard) return 'Clipboard unavailable, copy the text by hand'

  try {
    await navigator.clipboard.writeText(text)
    return 'Copied to clipboard'
  } catch (error) {
    return `No permission to write: ${error.name}`
  }
}

document.querySelector('#coupon').addEventListener('click', async () => {
  console.log(await copyText('COURSE-20'))
})
Result
Copied to clipboard

The result appears after clicking the button on a page opened over HTTPS. On a page opened over plain HTTP, the navigator.clipboard object doesn’t exist, and the function returns the first message.

Browser support

#

Newly available · since 2024

Works in the current versions of all major browsers. Older versions may not support it.

  • Chrome
  • Edge
  • Firefox
  • Safari

Good practices

#
  • Call writeText() from inside a click handler. Some browsers block copying without a user action.
  • Always handle a rejected promise and let the user know whether copying succeeded, e.g. by changing the button’s text to “Copied!”.
  • navigator.clipboard doesn’t exist on pages without HTTPS. Check for it before use, e.g. with navigator.clipboard?.writeText.

Related entries

#

Spotted a mistake or missing an example? Write to us.