← Controllers

clipboard

Copy text to clipboard with visual feedback.

Live Demo

npm install @11ty/eleventy

Usage

<button data-controller="clipboard"
        data-clipboard-text-value="Text to copy"
        data-action="click->clipboard#copy">
  <span data-clipboard-target="label">Copy</span>
</button>

Targets

Target Purpose
label Text that changes to show feedback

Values

Value Type Default Description
text String Text to copy
successText String "Copied!" Success message
duration Number 2000 Feedback duration (ms)

Source

import { Controller } from "@hotwired/stimulus";

export default class extends Controller {
  static targets = ["label"];
  static values = {
    text: String,
    successText: { type: String, default: "Copied!" },
    duration: { type: Number, default: 2000 },
  };

  async copy() {
    const text = this.textValue || this.element.textContent;

    try {
      await navigator.clipboard.writeText(text);
      this.showSuccess();
    } catch (err) {
      console.error("Failed to copy:", err);
    }
  }

  showSuccess() {
    if (this.hasLabelTarget) {
      const originalText = this.labelTarget.textContent;
      this.labelTarget.textContent = this.successTextValue;

      setTimeout(() => {
        this.labelTarget.textContent = originalText;
      }, this.durationValue);
    }
  }
}

Use with Code Blocks

<div class="code-block">
  <div class="code-block-header">
    <span>package.json</span>
    <button data-controller="clipboard"
            data-clipboard-text-value="npm install"
            data-action="click->clipboard#copy">
      <span data-clipboard-target="label">Copy</span>
    </button>
  </div>
  <pre><code>npm install</code></pre>
</div>