logo oujood
🔍

Clipboard API JavaScript

La Clipboard API permet à une page web de lire et d'écrire dans le presse-papiers de l'utilisateur par programmation. Elle remplace les anciennes commandes document.execCommand('copy') — dépréciées — avec une API moderne basée sur les Promises.

OUJOOD.COM

Copier un extrait de code, un lien, un mot de passe généré — c'est une fonctionnalité attendue dans beaucoup d'interfaces web. Pendant longtemps, JavaScript s'en sortait avec document.execCommand('copy'), une commande bricolée, synchrone, et officiellement dépréciée depuis plusieurs années.

La Clipboard API moderne règle ça proprement. Elle expose navigator.clipboard, un objet avec des méthodes asynchrones pour lire et écrire dans le presse-papiers — texte, HTML ou images. Comme pour les notifications, l'accès en lecture nécessite une permission explicite de l'utilisateur.

Copier du texte dans le presse-papiers

writeText() écrit une chaîne dans le presse-papiers. C'est l'opération la plus courante — celle derrière tous les boutons "Copier le code" :

Exemple :   📋 Copier le code

async function copierTexte(texte) {
  try {
    await navigator.clipboard.writeText(texte);
    console.log('Texte copié dans le presse-papiers.');
  } catch (erreur) {
    console.error('Échec de la copie :', erreur);
  }
}

// Copier le contenu d'un élément au clic
document.getElementById('btnCopier').addEventListener('click', () => {
  const code = document.getElementById('monCode').textContent;
  copierTexte(code);
});

Lire le contenu du presse-papiers

readText() lit le texte actuellement dans le presse-papiers. Cette opération nécessite que l'utilisateur accorde la permission clipboard-read — le navigateur affiche une demande d'autorisation :

Exemple :   📋 Copier le code

async function lirePresseePapiers() {
  try {
    const texte = await navigator.clipboard.readText();
    console.log('Contenu du presse-papiers :', texte);
    document.getElementById('champColler').value = texte;
  } catch (erreur) {
    // Permission refusée ou presse-papiers vide
    console.error('Lecture impossible :', erreur);
  }
}

Retour visuel après une copie

Un bon bouton "Copier" confirme visuellement que l'action a réussi. Voici le pattern classique avec changement de texte temporaire :

Exemple :   📋 Copier le code

async function copierAvecFeedback(texte, bouton) {
  try {
    await navigator.clipboard.writeText(texte);

    // Confirmer visuellement la copie
    const labelOriginal = bouton.textContent;
    bouton.textContent = '✓ Copié !';
    bouton.disabled = true;

    // Remettre le bouton dans son état initial après 2 secondes
    setTimeout(() => {
      bouton.textContent = labelOriginal;
      bouton.disabled = false;
    }, 2000);

  } catch (erreur) {
    bouton.textContent = '✗ Erreur';
    setTimeout(() => { bouton.textContent = 'Copier'; }, 2000);
  }
}

document.getElementById('btnCopier').addEventListener('click', function() {
  copierAvecFeedback('npm install mon-paquet', this);
});

Écrire du contenu riche dans le presse-papiers

La méthode write() (sans le suffixe "Text") accepte plusieurs formats simultanément — utile pour copier à la fois du HTML formaté et du texte brut en fallback :

Exemple :   📋 Copier le code

async function copierHtml(html, texteBrut) {
  try {
    const item = new ClipboardItem({
      'text/html': new Blob([html], { type: 'text/html' }),
      'text/plain': new Blob([texteBrut], { type: 'text/plain' })
    });

    await navigator.clipboard.write([item]);
    console.log('Contenu riche copié.');
  } catch (erreur) {
    console.error('Échec :', erreur);
  }
}

// Copier un tableau HTML avec fallback texte
copierHtml(
  '<table><tr><td>Alice</td><td>42</td></tr></table>',
  'Alice\t42'
);

Copier une image dans le presse-papiers

On peut aussi copier une image en la convertissant en Blob PNG. Le support varie selon les navigateurs, Chrome étant le plus avancé :

Exemple :   📋 Copier le code

async function copierImage(urlImage) {
  try {
    // Télécharger l'image et la convertir en Blob
    const reponse = await fetch(urlImage);
    const blob = await reponse.blob();

    const item = new ClipboardItem({ 'image/png': blob });
    await navigator.clipboard.write([item]);
    console.log('Image copiée dans le presse-papiers.');
  } catch (erreur) {
    console.error('Impossible de copier l\'image :', erreur);
  }
}

copierImage('/images/capture.png');

Vérifier les permissions avec l'API Permissions

Avant de tenter une lecture, on peut vérifier si la permission est déjà accordée pour éviter d'afficher une demande inutile :

Exemple :   📋 Copier le code

async function verifierPermissionLecture() {
  try {
    const permission = await navigator.permissions.query({
      name: 'clipboard-read'
    });

    console.log('Permission lecture :', permission.state);
    // "granted" | "denied" | "prompt"

    if (permission.state === 'granted') {
      lirePresseePapiers();
    }
  } catch (erreur) {
    console.error('Permissions API non disponible :', erreur);
  }
}

Fallback pour les navigateurs plus anciens

Si navigator.clipboard n'est pas disponible, on peut se rabattre sur la méthode historique avec execCommand — toujours fonctionnelle dans les vieux navigateurs malgré sa dépréciation :

Exemple :   📋 Copier le code

async function copierCompatible(texte) {
  // API moderne disponible
  if (navigator.clipboard) {
    try {
      await navigator.clipboard.writeText(texte);
      return true;
    } catch (e) { /* continuer vers le fallback */ }
  }

  // Fallback : sélection + execCommand (déprécié mais fonctionnel)
  const zone = document.createElement('textarea');
  zone.value = texte;
  zone.style.position = 'fixed';
  zone.style.opacity = '0';
  document.body.appendChild(zone);
  zone.select();
  document.execCommand('copy');
  document.body.removeChild(zone);
  return true;
}

Sécurité et bonnes pratiques

Quelques règles importantes à garder en tête :

  • HTTPS obligatoire : navigator.clipboard n'est accessible que sur des pages sécurisées (ou localhost).
  • Écriture sans permission : writeText() fonctionne sans permission explicite tant qu'elle est déclenchée par un geste utilisateur (clic, touche).
  • Lecture avec permission : readText() nécessite la permission clipboard-read. Ne l'utilisez que si c'est vraiment utile — beaucoup d'utilisateurs refusent cette permission.
  • Toujours gérer les erreurs avec try/catch : la permission peut être refusée, révoquée, ou le presse-papiers peut être vide.

Par carabde | Mis à jour le 17 avril 2026


chapitre précédent   sommaire   chapitre suivant