Copy buttons copy a value to the clipboard on click and show a "Copied!" confirmation with a check icon. They extend the component and come in three variants.
All variants use the same inner markup: a span (shown by default) and a span (shown on success). Each span contains an icon.
Icon + Text
The default copy button with a copy icon and "Copy" label. Best for standalone copy actions where the purpose needs to be clear.
Default
Copied state
<button class="button is-small is-outline copy-btn" data-copy="value" type="button">
<span class="copy-btn-default">{{icon:copy}} Copy</span>
<span class="copy-btn-copied">{{icon:check}} Copied!</span>
</button>
Icon Only
hides the text labels and shows only the icon. Best for compact UI: code blocks, table cells, and dense layouts. Always include aria-label.
Default
Copied state
<button class="button is-small is-outline copy-btn is-icon-only" data-copy="value" data-tooltip="Copy" type="button" aria-label="Copy">
<span class="copy-btn-default">{{icon:copy}}</span>
<span class="copy-btn-copied">{{icon:check}}</span>
</button>
Ghost
removes the background and border for a minimal, inline copy action. Best for use alongside content where a button would be too heavy.
Default
Copied state
<button class="button copy-btn is-ghost" data-copy="value" data-tooltip="Copy" type="button" aria-label="Copy">
<span class="copy-btn-default">{{icon:copy}}</span>
<span class="copy-btn-copied">{{icon:check}}</span>
</button>
Data Attributes
| Attribute | Description |
|---|---|
data-copy |
Static text value to copy |
data-clipboard-target |
CSS selector for an element whose text content should be copied |
data-download |
Same-origin file URL to download instead of copying |
data-download-name |
Optional filename for the downloaded file |
Use data-copy for static values (tokens, URLs). Use data-clipboard-target for dynamic content (code blocks). A data-download button composes with the same styling but downloads a file — it carries no copy attributes, so the two behaviours never collide on one button.
JavaScript
Include assets/js/copy-button.js on any page using copy buttons. The script handles all elements via event delegation. No per-button initialisation needed.
Optional config: sites that serve an icon sprite can render the feedback icons as <use> refs instead of the default inline path data. The config is read at render time, so ordering is forgiving — but declare it before the module for clarity:
<script>
window.bdCopyButtonConfig = { spritePath: "/assets/images/svg-icons/_sprite.svg" };
</script>
<script src="/assets/js/copy-button.js" defer></script>
The sprite must be same-origin and contain a #check symbol. Without config the module stays dependency-free.
Accessibility
- Always include
aria-label="Copy"on icon-only and ghost variants - The copied state provides visual feedback via the check icon and green colour
Variant Summary
| Variant | Classes | Use For |
|---|---|---|
| Icon + Text | Standalone copy actions | |
| Icon Only | .copy-btn.is-icon-only |
Code blocks, compact UI |
| Ghost | .copy-btn.is-ghost |
Inline, minimal contexts |
Use in another product
The design system installs once per product:
npm install github:bydefaultstudio/design-system-dist#semver:^4.7.0
This component's styles ship in design-system.css. Its behaviour ships as dist/js/copy-button.js — copy it into the product's served assets and include it once per page:
<script src="assets/js/copy-button.js" defer></script>