Quick Tour of the Clipboard API

copy and paste concept

Modern Copy, Cut, and Paste on the Web

If you’ve ever needed to copy, cut, or paste content in a web app, the Clipboard API is the modern way to do it—no more relying on deprecated document.execCommand(). Available in secure contexts, it lets you asynchronously read from and write to the system clipboard, and respond to user clipboard actions via events.

What it offers

Security and permissions

Clipboard access is sensitive. Browsers gate it behind permissions and user gestures:

				
					<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Clipboard API Demo</title>
    <link href="style.css" rel="stylesheet">
    <script src="clipboardAPI.js" defer></script>
</head>

<body>
    <h1>Clipboard API Demo</h1>
    
    <div class="demo-section">
        <h2>Writing to the Clipboard</h2>
        <p id="text-to-copy">This is the text that will be copied to your clipboard when you click the button.</p>
        <button id="copy-btn">Copy Text</button>
    </div>
    
    <div class="demo-section">
        <h2>Reading from the Clipboard</h2>
        <p>Click the button below to paste content from your clipboard into the text area.</p>
        <textarea id="paste-area" placeholder="Pasted content will appear here..."></textarea>
        <button id="paste-btn">Paste Text</button>
    </div>
    
    <p class="status">Status: <span id="status-message">Ready</span></p>
</body>

</html>
				
			
				
					body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    line-height: 1.6;
    background-color: #f4f7f9;
    color: #333;
    max-width: 800px;
    margin: 2rem auto;
    padding: 0 1rem;
}

h1,
h2 {
    color: #005a9c;
}

.demo-section {
    background-color: #fff;
    border: 1px solid #e0e0e0;
    border-radius: 8px;
    padding: 1.5rem;
    margin-bottom: 2rem;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}

#text-to-copy {
    background-color: #eef5ff;
    padding: 1rem;
    border-radius: 4px;
    border: 1px dashed #b3d4fc;
}

button {
    background-color: #007bff;
    color: white;
    border: none;
    padding: 10px 15px;
    border-radius: 5px;
    cursor: pointer;
    font-size: 1rem;
    transition: background-color 0.2s;
    margin-top: 10px;
}

button:hover {
    background-color: #0056b3;
}

textarea {
    width: 95%;
    min-height: 100px;
    padding: 10px;
    border-radius: 5px;
    border: 1px solid #ccc;
    font-size: 1rem;
    margin-top: 10px;
    display: block;
}

.status {
    text-align: center;
    color: #555;
    font-style: italic;
}
				
			
				
					// Wait for the DOM to be fully loaded before running our script
document.addEventListener('DOMContentLoaded', () => {
	// Select all the elements we'll need to interact with
	const copyBtn = document.querySelector('#copy-btn');
	const textToCopy = document.querySelector('#text-to-copy');
	const pasteBtn = document.querySelector('#paste-btn');
	const pasteArea = document.querySelector('#paste-area');
	const statusMessage = document.querySelector('#status-message');

	// --- WRITE TO CLIPBOARD ---

	copyBtn.addEventListener('click', async () => {
		// First, check if the Clipboard API is available in the browser
		if (!navigator.clipboard) {
			statusMessage.textContent =
				'Clipboard API not supported by your browser.';
			return;
		}

		try {
			// Get the text from our paragraph element
			const text = textToCopy.innerText;

			// Use the writeText() method to copy the text.
			// This is an asynchronous operation, so we use await.
			await navigator.clipboard.writeText(text);

			// Update the status message to give the user feedback
			statusMessage.textContent = 'Text copied to clipboard!';
			console.log('Text successfully copied.');
		} catch (err) {
			// If there's an error, log it to the console and update the status
			statusMessage.textContent = 'Failed to copy text.';
			console.error('Failed to copy text: ', err);
		}
	});

	// --- READ FROM CLIPBOARD ---

	pasteBtn.addEventListener('click', async () => {
		if (!navigator.clipboard) {
			statusMessage.textContent =
				'Clipboard API not supported by your browser.';
			return;
		}

		try {
			// Use the readText() method to get content from the clipboard.
			// This is also asynchronous.
			// The browser will likely ask the user for permission here for security.
			const text = await navigator.clipboard.readText();

			// Set the value of the textarea to the text we just read
			pasteArea.value = text;

			// Provide user feedback
			statusMessage.textContent = 'Text pasted from clipboard!';
			console.log('Text successfully pasted.');
		} catch (err) {
			// Handle any errors, such as the user denying permission
			statusMessage.textContent = 'Failed to paste text.';
			console.error('Failed to read from clipboard: ', err);
		}
	});
});

				
			

Key interfaces

Gotchas and best practices

Why use it

The Clipboard API delivers a secure, user-friendly, and flexible approach to clipboard operations, aligning with modern web security models and enabling richer interactions than legacy methods. If your app involves editing, sharing, or quick data transfer, it’s the right tool for the job.

more posts:
Online video streaming platform and digital content management concept with media player interface, cloud library, and multimedia files on laptop, representing content distribution, video marketing
Code

Breaking into the Pipeline: Real-Time Frame Manipulation with the Insertable Streams for MediaStreamTrack API

The experimental Insertable Streams for MediaStreamTrack API closes a long-standing gap in web multimedia by treating live camera feeds as standard Web Streams. By piping individual VideoFrame objects through a TransformStream and recording the transformed output via MediaRecorder, developers can execute frame-by-frame processing—like real-time filtering, watermarking, and computer vision overlays—without relying on hidden canvas hacks.

Discover More »
Apps & Custom Software

What Building Our Own App Taught Us About Building Yours

When Hess WebTech built and launched Tericipe—an Android app that turns printed recipes into a searchable digital collection—in under three months, we had to live with every decision we usually advise clients on. From testing against real-world messy data and handling AI uncertainty to server-side payment security and post-launch maintenance, here are five crucial lessons from our own build that apply to almost any software project.

Discover More »