Start · Sprachen · JavaScript · Referenz · Clipboard.write()

Clipboard.write()

Methode

Schreibt ein oder mehrere <code>ClipboardItem</code>-Objekte (z. B. Bilder, HTML, Text) asynchron in die Zwischenablage und gibt ein Promise zurück.

seit JavaScript Baseline 2024: Chrome 76+, Edge 79+, Firefox 127+, Kategorie: webapi

Signatur

Clipboard.prototype.write(data)

Beschreibung

Die Methode navigator.clipboard.write() ist der flexible Teil der asynchronen Clipboard-API. Anders als writeText(), das nur einfachen Text schreibt, nimmt write() ein Array von ClipboardItem-Objekten entgegen. Jedes davon kann dieselben Inhalte in mehreren MIME-Typen enthalten, etwa text/html und text/plain gleichzeitig. Die Zielanwendung sucht sich dann das passende Format aus.

Typische Einsätze sind Schaltflächen wie „Bild kopieren“ (PNG aus einem <canvas> oder von einer URL), „Als formatierten Text kopieren“ für Rich-Text-Editoren oder das Kopieren von Diagrammen und Tabellen. Offiziell garantiert sind nur text/plain, text/html und image/png. Chromium unterstützt zusätzlich eigene Formate mit dem Präfix web (z. B. "web application/json").

Die Methode funktioniert nur in einem sicheren Kontext (HTTPS oder localhost). Meist braucht sie außerdem eine vorübergehende Nutzeraktivierung, also einen direkten Klick oder Tastendruck. Die Werte eines ClipboardItem dürfen auch Promise<Blob> sein. So kann man den Schreibvorgang synchron im Klick-Handler starten, obwohl die Daten erst später geladen werden. Das ist besonders für Safari wichtig.

Parameter

Name Typ Default Beschreibung
$data Pflicht ClipboardItem[] Array von ClipboardItem-Objekten. Jedes Objekt ordnet MIME-Typen Werten zu. Erlaubt sind Blob, string oder ein Promise, das zu einem davon auflöst. Die meisten Browser unterstützen derzeit nur ein Element im Array.

Rückgabewert

Typ
Promise<void>
Beschreibung
Promise, das mit undefined erfüllt wird, sobald die Daten in der Zwischenablage stehen. Es wird mit einer DOMException abgelehnt, z. B. NotAllowedError (keine Berechtigung, keine Nutzeraktivierung oder Dokument ohne Fokus) oder DataError bzw. NotAllowedError bei nicht unterstützten MIME-Typen.

Beispiele

HTML und Klartext gleichzeitig kopieren

const copyRichText = async (html, text) => {
  const item = new ClipboardItem({
    'text/html': new Blob([html], { type: 'text/html' }),
    'text/plain': new Blob([text], { type: 'text/plain' })
  });
  try {
    await navigator.clipboard.write([item]);
    console.log('Formatierter Text kopiert');
  } catch (err) {
    console.error('Kopieren fehlgeschlagen:', err.name);
  }
};

document.querySelector('#copy').addEventListener('click', () => {
  copyRichText('<strong>Hallo</strong> Welt', 'Hallo Welt');
});
Formatierter Text kopiert

Canvas-Inhalt als PNG-Bild kopieren

const canvas = document.querySelector('canvas');

const canvasToBlob = (cv) =>
  new Promise((resolve) => cv.toBlob(resolve, 'image/png'));

document.querySelector('#copy-image').addEventListener('click', async () => {
  const blob = await canvasToBlob(canvas);
  await navigator.clipboard.write([
    new ClipboardItem({ 'image/png': blob })
  ]);
  console.log('Bild in Zwischenablage:', blob.size, 'Bytes');
});
Bild in Zwischenablage: 18342 Bytes

Bild von URL kopieren – Safari-kompatibel mit Promise im ClipboardItem

document.querySelector('#copy-logo').addEventListener('click', async () => {
  // Promise direkt übergeben, damit die Nutzeraktivierung nicht verfällt
  const blobPromise = fetch('/img/logo.png').then((res) => {
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    return res.blob();
  });

  try {
    await navigator.clipboard.write([
      new ClipboardItem({ 'image/png': blobPromise })
    ]);
    console.log('Logo kopiert');
  } catch (err) {
    console.error(err);
  }
});
Logo kopiert

Unterstützung prüfen und auf writeText zurückfallen

const copy = async (text, html) => {
  if (navigator.clipboard?.write && typeof ClipboardItem !== 'undefined') {
    const supportsHtml = ClipboardItem.supports?.('text/html') ?? true;
    if (supportsHtml) {
      await navigator.clipboard.write([
        new ClipboardItem({
          'text/html': new Blob([html], { type: 'text/html' }),
          'text/plain': new Blob([text], { type: 'text/plain' })
        })
      ]);
      return 'rich';
    }
  }
  await navigator.clipboard.writeText(text);
  return 'plain';
};

document.querySelector('#btn').addEventListener('click', async () => {
  console.log(await copy('Preis: 42 €', '<b>Preis:</b> 42 €'));
});
rich

// Wichtig · Fallstricke

  • Sicherer Kontext: navigator.clipboard ist nur über HTTPS oder localhost verfügbar. Über http:// ist es undefined.
  • Nutzeraktivierung: Rufe die Methode direkt in einem Klick- oder Tastatur-Handler auf. Safari lehnt Aufrufe nach längeren await-Ketten ab. Übergib dort ein Promise<Blob> im ClipboardItem, statt vorher zu warten.
  • Fokus: Hat das Dokument keinen Fokus (z. B. bei offenen DevTools), schlägt der Aufruf mit NotAllowedError fehl.
  • Berechtigungen: Chromium kennt die Berechtigung clipboard-write, die in aktiven Tabs automatisch erteilt wird. Firefox und Safari unterstützen diese Abfrage nicht. Verlasse dich also nicht auf navigator.permissions.query().
  • MIME-Typen: Verlässlich funktionieren nur text/plain, text/html und image/png. JPEG wird in der Regel abgelehnt, also vorher über ein Canvas in PNG umwandeln. Mit ClipboardItem.supports() (neuere Browser) lässt sich die Unterstützung prüfen.
  • Nur ein Element: Mehrere ClipboardItems im Array werden von den meisten Browsern nicht unterstützt.
  • Sicherheit: Der Browser bereinigt HTML aus der Zwischenablage beim Einfügen. Trotzdem gilt: Wer Nutzereingaben als text/html kopiert, sollte sie vorher sauber maskieren, denn die Zielanwendung könnte das HTML ungefiltert übernehmen.
  • Browser-Unterstützung: Firefox unterstützt ClipboardItem und write() ohne Konfigurationsschalter erst ab Version 127. Ältere Browser brauchen eine Fallback-Lösung über writeText() oder das veraltete document.execCommand('copy').