data-copy

Copy to clipboard via data attributes. Add data-copy or data-copy-target to any button for clipboard functionality with visual and screen reader feedback.

Overview

The data-copy attribute enhances native buttons with clipboard copy behavior. No wrapper element needed — just add the attribute directly to a <button>.

<button data-copy="npm install vanilla-breeze">Copy install command</button>

How It Works

Add one of these attributes to any <button>:

  • data-copy — the attribute value is the text to copy
  • data-copy-target — a CSS selector pointing to another element whose textContent will be copied

On click, the text is written to the clipboard, data-state="copied" is set for 1.5 seconds, a screen reader announcement fires, and a copy custom event is dispatched.

Attributes

Attribute Type Description
data-copy string Static text to copy to the clipboard.
data-copy-target string CSS selector for the element whose textContent to copy.
data-state string Set to "copied" automatically for 1.5s after a successful copy. Use in CSS for feedback styling.
data-copy-init boolean Set automatically to prevent double-binding. Do not set manually.

Copy from Target Element

Use data-copy-target with a CSS selector to copy text from another element on the page.

const greeting = "Hello, world!";
<pre><code id="code-block">const greeting = "Hello, world!";</code></pre> <button data-copy-target="#code-block">Copy code</button>

With Icons

Pair with <icon-wc> for a more visual button.

<button data-copy="https://vanilla-breeze.dev"> <icon-wc name="copy" size="sm"></icon-wc> Copy link </button>

Events

The button dispatches a copy event on successful clipboard write.

Event Detail Description
copy { text: string } Fired after text is copied. The detail.text property contains the copied string.
const btn = document.querySelector('[data-copy]'); btn.addEventListener('copy', (e) => { console.log('Copied:', e.detail.text); });

Common Use Cases

Code Block Copy Button

Position a copy button inside a code block:

npm install vanilla-breeze
<div style="position: relative;"> <pre><code id="snippet">npm install vanilla-breeze</code></pre> <button data-copy-target="#snippet" class="ghost small" style="position: absolute; top: 0.5rem; right: 0.5rem;"> <icon-wc name="copy" size="sm"></icon-wc> </button> </div>

Share Link

Quick share-by-link button:

<button data-copy="https://vanilla-breeze.dev/docs" class="secondary"> <icon-wc name="link" size="sm"></icon-wc> Share link </button>

Styling Feedback

The data-state="copied" attribute is set for 1.5 seconds after copying. Use it to style the copied state:

[data-copy][data-state="copied"], [data-copy-target][data-state="copied"] { color: var(--color-success); }

The default styles change the button text color to --color-success during the copied state.

Dynamic Buttons

Buttons added to the DOM after page load are automatically enhanced via a MutationObserver. No manual initialization is needed.

// Dynamically added buttons are auto-enhanced via MutationObserver const btn = document.createElement('button'); btn.dataset.copy = 'Hello from JS'; btn.textContent = 'Copy greeting'; document.body.appendChild(btn); // btn is ready to use — no manual init needed

Accessibility

  • Uses aria-live="polite" to announce "Copied to clipboard" to screen readers
  • The announcement element is visually hidden with sr-only and removed after 1 second
  • Works with any focusable button element, preserving keyboard accessibility
  • No wrapper element — the button is the interactive element, improving the accessibility tree
  • Falls gracefully when the Clipboard API is unavailable or permission is denied