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 copydata-copy-target— a CSS selector pointing to another element whosetextContentwill 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.
<section> <h2>Accessibility</h2> <ul> <li>Uses <code>aria-live="polite"</code> to announce "Copied to clipboard" to screen readers</li> <li>The announcement element is visually hidden with <code>sr-only</code> and removed after 1 second</li> <li>Works with any focusable button element, preserving keyboard accessibility</li> <li>No wrapper element — the button <em>is</em> the interactive element, improving the accessibility tree</li> <li>Falls gracefully when the Clipboard API is unavailable or permission is denied</li> </ul> </section>