Modern copy to clipboard library with no Flash dependency, just 2kb gzipped
npx @tessl/cli install tessl/npm-clipboard@2.0.0Clipboard.js is a modern clipboard library that provides programmatic and declarative interfaces for copying and cutting text to the system clipboard. It eliminates the need for Flash or other plugins, offering a lightweight 2kb solution with full browser compatibility and comprehensive event handling.
npm install clipboardimport ClipboardJS from "clipboard";For CommonJS:
const ClipboardJS = require("clipboard");UMD (browser global):
<script src="https://unpkg.com/clipboard@2/dist/clipboard.min.js"></script>
<!-- Creates global ClipboardJS -->import ClipboardJS from "clipboard";
// Initialize with CSS selector
const clipboard = new ClipboardJS('.copy-btn');
// Listen for events
clipboard.on('success', function(e) {
console.log('Copied:', e.text);
e.clearSelection(); // Clear text selection
});
clipboard.on('error', function(e) {
console.error('Failed to copy');
});
// Cleanup when done
clipboard.destroy();HTML declarative usage:
<!-- Copy from another element -->
<input id="source" value="Text to copy" />
<button class="copy-btn" data-clipboard-target="#source">Copy</button>
<!-- Copy specific text -->
<button class="copy-btn" data-clipboard-text="Hello World">Copy Text</button>
<!-- Cut from input/textarea -->
<textarea id="editor">Content to cut</textarea>
<button class="copy-btn" data-clipboard-action="cut" data-clipboard-target="#editor">Cut</button>Creates a new clipboard instance with event listeners attached to trigger elements.
/**
* Creates a clipboard instance with event listeners
* @param trigger CSS selector, element, or collection of elements to attach listeners to
* @param options Configuration options for customizing behavior
*/
constructor(
trigger: string | Element | NodeListOf<Element>,
options?: ClipboardJS.Options
): ClipboardJS;Event Handling
Subscribe to clipboard operation results.
/**
* Subscribe to clipboard events
* @param type Event type - 'success' for successful operations, 'error' for failures
* @param handler Callback function receiving event details
*/
on(type: 'success' | 'error', handler: (e: ClipboardJS.Event) => void): this;
/**
* Unsubscribe from clipboard events
* @param type Event type to unsubscribe from
* @param handler Optional specific handler to remove, if omitted removes all handlers for the type
*/
off(type: 'success' | 'error', handler?: (e: ClipboardJS.Event) => void): this;
/**
* Subscribe to an event that will only fire once
* @param type Event type - 'success' for successful operations, 'error' for failures
* @param handler Callback function receiving event details
*/
once(type: 'success' | 'error', handler: (e: ClipboardJS.Event) => void): this;
/**
* Emit an event manually (inherited from tiny-emitter)
* @param type Event type to emit
* @param args Arguments to pass to event handlers
*/
emit(type: string, ...args: any[]): this;Lifecycle Management
Clean up event listeners and destroy the clipboard instance.
/**
* Destroy the clipboard instance and remove all event listeners
*/
destroy(): void;Programmatic Copy
Execute copy operations programmatically without requiring DOM events.
/**
* Copy text or element content to clipboard
* @param target String to copy or DOM element to copy from
* @param options Configuration options
* @returns The text that was copied
*/
static copy(
target: string | Element,
options?: { container?: Element }
): string;Programmatic Cut
Execute cut operations programmatically for form elements.
/**
* Cut text from form elements (input/textarea)
* @param target String selector or DOM element to cut from
* @returns The text that was cut
*/
static cut(target: string | Element): string;Feature Detection
Check if clipboard operations are supported in the current browser.
/**
* Check if clipboard operations are supported
* @param action Optional action(s) to check - string for single action or array for multiple, defaults to ['copy', 'cut']
* @returns Whether the specified actions are supported
*/
static isSupported(action?: string | string[]): boolean;Options for customizing clipboard behavior.
interface ClipboardJS.Options {
/**
* Custom function to determine the action (copy/cut) based on trigger element
* @param elem The trigger element that was clicked
* @returns Action to perform
*/
action?(elem: Element): 'copy' | 'cut';
/**
* Custom function to determine the target element to copy/cut from
* @param elem The trigger element that was clicked
* @returns Element to copy/cut from
*/
target?(elem: Element): Element;
/**
* Custom function to determine the text to copy
* @param elem The trigger element that was clicked
* @returns Text to copy to clipboard
*/
text?(elem: Element): string;
/**
* Container element for focus management
* Useful for Bootstrap modals or other focus-changing libraries
*/
container?: Element;
}Event object passed to success/error handlers.
interface ClipboardJS.Event {
/** The action that was performed */
action: string;
/** The text that was copied/cut */
text: string;
/** The trigger element that initiated the action */
trigger: Element;
/** Method to clear the current text selection */
clearSelection(): void;
}Declarative API using HTML5 data attributes for configuration without JavaScript.
data-clipboard-action
"copy" (default) or "cut"data-clipboard-target
data-clipboard-text
The library throws errors for invalid configurations:
Error: "Invalid "action" value, use either "copy" or "cut""Error: "Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute"Error: "Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes"Error: "Invalid "target" value, use a valid Element"Supported Browsers:
Graceful Degradation:
Use ClipboardJS.isSupported() to detect support and provide fallback UI (e.g., "Press Ctrl+C to copy" message).
Dynamic Target Selection:
new ClipboardJS('.btn', {
target: function(trigger) {
// Copy from next sibling element
return trigger.nextElementSibling;
}
});Dynamic Text Generation:
new ClipboardJS('.btn', {
text: function(trigger) {
// Copy from aria-label attribute
return trigger.getAttribute('aria-label');
}
});Modal Container Support:
new ClipboardJS('.btn', {
container: document.getElementById('modal')
});Feature Detection with Fallback:
if (ClipboardJS.isSupported()) {
// Initialize clipboard functionality
const clipboard = new ClipboardJS('.copy-btn');
} else {
// Show manual copy instructions
document.querySelectorAll('.copy-btn').forEach(btn => {
btn.style.display = 'none';
});
}