v145 · Web APIs · Clipboard
Clipboardchange event
Chrome 145 ships the clipboardchange event — a window event that fires when the system clipboard contents change. The event requires sticky activation (a recent user gesture on the page) and the clipboard-read permission to deliver clipboard data in the handler. The event signals a change occurred; reading the value is a separate guarded step.
concepts
-
Clipboard Monitor
Live monitor that listens for
clipboardchangeevents. Copy text anywhere and watch the event fire. Includes a permission request flow to read the new clipboard value inside the event handler. -
Activation & Permissions
Explains the two gating requirements Chrome 145 enforces: sticky activation (a recent user interaction with the page) and
clipboard-readpermission. Shows a matrix of what is available at each permission state. -
Clipboard Differ
Subscribe to
clipboardchange, snapshot each change, and visually diff the new payload against the previous — character-level insertions in green, deletions in red. Useful for clipboard managers and paste-aware editors. -
Paste Preview
A text editor that shows a "Paste ready" preview banner when
clipboardchangefires. After sticky activation, copy text anywhere — the banner appears immediately with a one-click insert action, demonstrating the real-world paste-preview UX pattern.
why it shipped
Rich text editors, code editors, and clipboard managers need to know when clipboard contents change to update paste-preview UI or enable a "Paste" action. Previously the only option was polling navigator.clipboard.readText() on a timer — noisy, battery-draining, and requiring a persistent permission. The clipboardchange event lets apps react immediately and request clipboard-read only when needed, inside the trusted event handler context.
the API
// Listen for clipboard changes on window
window.addEventListener('clipboardchange', async () => {
// The event fires — but to read the value, check permission first
const { state } = await navigator.permissions.query({ name: 'clipboard-read' });
if (state === 'granted') {
const text = await navigator.clipboard.readText();
console.log('Clipboard changed:', text);
} else if (state === 'prompt') {
// Inside a trusted event handler — browser can show permission UI
try {
const text = await navigator.clipboard.readText(); // prompts user
console.log('Clipboard changed:', text);
} catch {
showManualPasteButton();
}
} else {
// 'denied' — signal change but can't read value
showPasteChangedBadge();
}
});
// Requires: sticky activation (user gesture) + clipboard-read permission
// The event itself fires without permission; reading the value needs permission