PlaygroundInstallDocs GitHubv1.3.0

MIT · zero dependencies · copy / cut / paste / format

The smarter clipboard solution.

Add clipboard actions and user feedback to any page using plain HTML attributes. Built-in toast notifications, text formatting, and nothing else to install.

Try the playground
npm i clipxjs

Playground

Change the options and use the live button. The code on the right updates as you go, and you can copy it straight into your project.

Action
Clean up (in click order)
Case (pick one)

Why ClipX.js?

A clipboard utility that handles the UI feedback too, so you don't need to wire up extra libraries or write the same handler in every project.

DeclarativeBehavior lives in your markup with data-clipx-* attributes. No custom event handlers.
Built-in feedbackCustomizable toasts and button messages, plus clear error toasts instead of silent failures.
Copy, cut, paste, formatClean text with chained formatters before it reaches the clipboard, or add your own.
Easy integrationEvent delegation means dynamically added buttons just work. Uses the Clipboard API with a copy fallback.

Installation

NPM

npm i clipxjs

CDN (use only one)

<script src="https://cdn.jsdelivr.net/npm/clipxjs/dist/clipx.min.js"></script>
<script src="https://unpkg.com/clipxjs/dist/clipx.min.js"></script>

Direct download

Download the ZIP from GitHub

Getting started

Initialize

ClipX is an alias of the clipx constructor, so naming your instance clipx doesn't shadow it.

var clipx = new ClipX();

// with a bundler
const ClipX = require("clipxjs");

Attach

attach() uses event delegation, so it also works for elements added later, and it is safe to call more than once.

clipx.attach(); // default: [data-clipx-text], [data-clipx-target], [data-clipx-paste]
clipx.attach(".copy-btn, .your-class"); // custom selectors
clipx.detach(); // remove all listeners

Configure

clipx.disable.msg = true;   // never change the element text
clipx.disable.toast = true; // never show toasts

clipx.setCustomStyles({
  toast: "background:#333;color:#fff;padding:12px;border-radius:5px;", // all toasts
  error: "background:#7a1f1f;"                                         // extra, for error toasts
});

Hide the toast icon with CSS:

.clipx-js-svg-icon { display: none; }

Attributes

Add these to any element that matches your attach() selector. If several source attributes are present, the priority is paste, then target, then text.

AttributeDescription
data-clipx-targetSelector of the element to copy (or cut) from. Inputs use their value; other elements their text.
data-clipx-textStatic text to copy.
data-clipx-pasteSelector of the element to paste into.
data-clipx-cutClear the target after copying. Only works with data-clipx-target.
data-clipx-formatComma-separated formatters applied before copy or paste: trim, uppercase, lowercase, capitalize, titlecase, collapse, singleline, striphtml.
data-clipx-msgCustom success message (default Copied! / Pasted!).
data-clipx-toastShow only the toast; leave the element's text unchanged.
data-clipx-disable-msgDon't change the element's text.
data-clipx-disable-toastDon't show the toast.
data-clipx-toast-positiontop or bottom (default).
data-clipx-durationMilliseconds the message stays visible (default 1500).

Examples

<!-- copy from an element -->
<p id="text-to-copy">This is the text to be copied.</p>
<button data-clipx-target="#text-to-copy">Copy Text</button>

<!-- static text with a custom message -->
<button data-clipx-text="Static text" data-clipx-msg="Text copied successfully!">Copy</button>

<!-- cut -->
<textarea id="text-to-cut">This text will be cut.</textarea>
<button data-clipx-target="#text-to-cut" data-clipx-cut>Cut</button>

<!-- paste -->
<textarea id="paste-here"></textarea>
<button data-clipx-paste="#paste-here">Paste</button>

<!-- toast only, on top, for 3 seconds -->
<button data-clipx-text="Hi" data-clipx-toast data-clipx-toast-position="top" data-clipx-duration="3000">Copy</button>

<!-- silent copy -->
<button data-clipx-text="Hi" data-clipx-disable-toast data-clipx-disable-msg>Copy</button>

Formatting

Formatters in data-clipx-format run left to right, before the text is copied or pasted. The case formatters (uppercase, lowercase, capitalize, titlecase) replace each other, so use only one of them per attribute.

FormatterEffect
trimRemove leading and trailing whitespace
uppercase / lowercaseChange case
capitalizeUppercase the first letter only
titlecaseCapitalize Each Word
collapseReplace runs of whitespace with one space
singlelineReplace line breaks with a space
striphtmlRemove HTML tags (and script/style content) and decode entities, leaving plain text
// add your own
clipx.addFormatter("reverse", function (text) {
  return text.split("").reverse().join("");
});
// <button data-clipx-text="abc" data-clipx-format="reverse">

JavaScript API

Use ClipX without attributes. Copy, cut and paste methods return Promises.

clipx.copyText("hello");                    // copy a string
clipx.cutText("hello", element);            // copy, then clear element
clipx.copyFromElement(element, "trim");     // optional format
clipx.cutFromElement(element, "trim");
clipx.pasteText();                          // resolves with clipboard text
clipx.pasteToElement(element, "uppercase");
clipx.format("  hi ", "trim,uppercase");    // sync, returns "HI"
clipx.addFormatter(name, fn);
clipx.attach(selector); clipx.detach();
clipx.setCustomStyles({ toast, error });

Events

ClipX dispatches bubbling events from the clicked element.

document.addEventListener("clipx:success", function (e) {
  console.log(e.target, e.detail.type); // "copy" | "cut" | "paste"
});

document.addEventListener("clipx:error", function (e) {
  console.log(e.detail.error);
});

Notes

  • Works in modern browsers. Copy uses the Clipboard API and falls back to execCommand("copy") if it is unavailable or blocked.
  • The Clipboard API requires a secure context (HTTPS or localhost).
  • Paste uses navigator.clipboard.readText(): it needs HTTPS, a user click, and usually a permission prompt. Support varies by browser, and an error toast shows when it isn't allowed.
  • Cutting from a non-input element sets its text to empty, which removes any child elements inside it.
  • Toast messages are inserted as plain text, so data-clipx-msg can't inject HTML.
  • Upgrading from 1.2.x? The default message is now Copied!, and the old isProcessing property is gone.