The Clipboard API

· 3 min read · Updated March 11, 2026 · beginner
javascript browser-api clipboard

The Clipboard API gives you programmatic access to the system clipboard. You can read text that users have copied and write text you want to let them paste elsewhere. It’s useful for building features like copy-to-clipboard buttons, paste handlers, and clipboard-powered workflows.

This API lives on navigator.clipboard and provides promise-based methods for reading and writing text. It’s supported in all modern browsers, but requires a secure context (HTTPS) in most cases.

Copying Text to Clipboard

The navigator.clipboard.writeText() method copies a string to the clipboard. Call it on navigator.clipboard:

async function copyToClipboard(text) {
  try {
    await navigator.clipboard.writeText(text);
    console.log('Text copied to clipboard');
  } catch (err) {
    console.error('Failed to copy:', err);
  }
}

// Usage
copyToClipboard('Hello, world!');

The method returns a promise that resolves when the copy succeeds. If the write fails—whether due to permissions, missing user activation, or an insecure context—the promise rejects.

Most browsers require what the spec calls transient user activation for clipboard writes. This means the code must run in response to a user action like a click. Wrap your copy function behind a button click to satisfy this requirement:

document.querySelector('.copy-btn').addEventListener('click', async () => {
  const text = document.querySelector('.code-block').textContent;
  await navigator.clipboard.writeText(text);
  // Show feedback to user
});

Reading Text from Clipboard

The navigator.clipboard.readText() method reads the current clipboard contents as a string:

async function readFromClipboard() {
  try {
    const text = await navigator.clipboard.readText();
    console.log('Clipboard contents:', text);
    return text;
  } catch (err) {
    console.error('Failed to read clipboard:', err);
  }
}

Reading is more restricted than writing. Browsers enforce permission prompts or require recent user interaction. Chromium browsers may prompt for clipboard-read permission. Firefox and Safari show an ephemeral context menu with a paste option.

This works reliably when triggered by a user action:

document.querySelector('.paste-btn').addEventListener('click', async () => {
  const clipboardText = await navigator.clipboard.readText();
  document.querySelector('.output').textContent = clipboardText;
});

Handling Permissions

The Permissions API lets you check and request clipboard permissions before attempting operations:

async function checkClipboardPermission() {
  const permission = await navigator.permissions.query({
    name: 'clipboard-read'
  });
  console.log('Clipboard permission:', permission.state);
  // Possible states: 'granted', 'denied', 'prompt'
}

Note that Firefox and Safari don’t support the clipboard permissions yet. They rely on transient user activation instead. Your code should handle both cases—check for permission support before querying:

async function safeReadClipboard() {
  // Check if Permissions API supports clipboard
  if ('permissions' in navigator) {
    try {
      const { state } = await navigator.permissions.query({ 
        name: 'clipboard-read' 
      });
      if (state === 'denied') {
        throw new Error('Clipboard access denied');
      }
    } catch (e) {
      // Firefox/Safari don't support this query
      console.log('Using fallback activation method');
    }
  }
  
  return navigator.clipboard.readText();
}

Browser Compatibility

The Clipboard API works in all modern browsers:

  • Chrome 66+
  • Firefox 87+
  • Safari 13.1+
  • Edge 79+

Key requirements:

  • Secure context: Most browsers require HTTPS. The API may be unavailable or throw errors on HTTP.
  • User activation: Writing requires the page to be in a state caused by user interaction. Reading has stricter requirements in some browsers.
  • iframe restrictions: If your content runs in an iframe, the parent page must allow clipboard access via the Permissions-Policy header:
Permissions-Policy: clipboard-read=(self), clipboard-write=(self)

For older browsers or edge cases, fall back to the legacy document.execCommand('copy') approach, though it’s clunkier and being phased out:

function fallbackCopy(text) {
  const textarea = document.createElement('textarea');
  textarea.value = text;
  textarea.style.position = 'fixed';
  textarea.style.left = '-9999px';
  document.body.appendChild(textarea);
  textarea.select();
  document.execCommand('copy');
  document.body.removeChild(textarea);
}

Use Cases

The Clipboard API enables several common patterns in web applications:

  • Copy buttons: Add one-click copy for code snippets, discount codes, or referral links
  • Paste handlers: Read clipboard content when users paste into input fields
  • Clipboard monitoring: Track when users paste specific content patterns
  • Data transfer: Move data between your app and other applications via clipboard

See Also