Créer un bouton de copie dans le presse-papiers accessible à tous
Un bouton de copie semble être l’une des commandes les plus simples d’un site. On clique, le texte est copié, puis le message “Copié” apparaît. Pourtant, une version fiable doit tenir compte des autorisations du navigateur, du clavier, des annonces des lecteurs d’écran, des longs extraits de code, des échecs de copie et des données sensibles.
C’est particulièrement utile pour les outils de développement. Une commande cURL, une séquence d’entités HTML, un mot de passe ou un lien de partage d’avatar ne sert vraiment que si le visiteur peut le transférer sans perdre de caractères. Web2Generators propose plusieurs exemples de résultats à copier, de son encodeur et décodeur HTML à son générateur de commandes cURL.
Voici un modèle à adapter à une documentation, un tableau de bord, un espace d’essai de code ou une application web.
Commencer par un vrai bouton et un libellé accessible
Inutile d’ajouter un gestionnaire de clic à une icône décorative ou à un div lorsqu’un élément <button> fournit déjà l’activation au clavier et la sémantique appropriée.
<section aria-labelledby="command-title">
<h2 id="command-title">Example command</h2>
<pre><code id="command">curl 'https://example.com/status'</code></pre>
<button type="button" id="copy-command" aria-describedby="copy-status">
Copy command
</button>
<span id="copy-status" role="status" aria-live="polite"></span>
</section>
Le libellé visible explique l’action. La zone de statut peut annoncer le succès ou l’échec de la copie sans déplacer le focus du bouton. Le rôle status implique déjà des annonces polies dans les API d’accessibilité modernes ; l’attribut explicite aria-live rend ici cette intention visible. Les exemples conservent les libellés anglais pour rester identiques à la version originale : traduisez les textes affichés et les messages pour votre interface.
Ne comptez pas sur la forme d’une icône ou sur une infobulle au survol pour expliquer la commande. Une icône de copie seule peut prêter à confusion, surtout dans une barre d’outils contenant plusieurs boutons similaires. “Copier l’URL”, “Copier le mot de passe” et “Copier la commande cURL” sont plus précis que “Copier” lorsque plusieurs résultats sont affichés.
Utiliser l’API Clipboard moderne
Pour un résultat textuel, navigator.clipboard.writeText() est l’API du navigateur prévue pour cette opération. Elle renvoie une promesse résolue lorsque le navigateur confirme la copie, ou rejetée s’il ne peut pas l’effectuer. Cette référence MDN est conservée en anglais : la version française contient une ancienne indication sur les autorisations qui ne reflète pas les exigences actuelles.
Chargez ce JavaScript après le HTML ci-dessus, par exemple depuis un script externe avec defer.
const copyButton = document.querySelector("#copy-command");
const command = document.querySelector("#command");
const status = document.querySelector("#copy-status");
copyButton.addEventListener("click", async () => {
status.textContent = "";
const text = command.textContent;
if (!navigator.clipboard?.writeText) {
status.textContent = "Automatic copying is unavailable. Select the text to copy it.";
return;
}
try {
await navigator.clipboard.writeText(text);
status.textContent = "Command copied.";
} catch {
status.textContent = "Could not copy automatically. Select the text and copy it manually.";
}
});
Cet exemple lit volontairement textContent, et non le balisage HTML. Il récupère le texte de l’élément de code sans sérialiser ses balises. textContent peut inclure le texte de descendants masqués : il ne garantit donc pas de copier uniquement ce qui est visible. Il signale aussi les échecs au lieu d’annoncer un succès fictif. Pour un bloc complexe avec coloration syntaxique, vérifiez si le texte contient des numéros de ligne ou des libellés masqués indésirables ; une chaîne source dédiée peut fournir une valeur plus fiable.
L’API Clipboard asynchrone exige un contexte sécurisé, comme HTTPS ou une origine de développement local appropriée. Les règles des navigateurs et leurs exigences d’activation par l’utilisateur diffèrent : appelez donc l’API directement depuis une action de l’utilisateur et testez les navigateurs visés. Une demande ou un refus d’autorisation n’indique pas nécessairement une erreur de programmation.
Ne jamais afficher “Copié” avant le succès
Une erreur courante consiste à modifier immédiatement le libellé du bouton, puis à lancer l’écriture dans le presse-papiers. Cela produit une fausse confirmation si la page n’a pas l’autorisation ou si le navigateur bloque l’opération.
Le message doit suivre le résultat de la promesse. Gardez le bouton utilisable pour une nouvelle tentative et prévoyez une sélection manuelle. Pour les utilisateurs du clavier, un textarea en lecture seule avec un libellé explicite est une solution utile à la place du bloc de code : ils peuvent y placer le focus, sélectionner son contenu et utiliser leur raccourci de copie habituel. Avec un textarea, lisez .value plutôt que .textContent.
Si vous remplacez le libellé par “Copié”, rétablissez-le après un court délai sans perturber le focus ; l’annonce doit rester compréhensible pour les technologies d’assistance. Pour un résultat particulièrement sensible, vous pouvez conserver “Copier le mot de passe” et utiliser un message à proximité.
Évitez d’afficher les messages d’exception bruts. Les détails des erreurs du navigateur peuvent être déroutants et varier selon la plateforme ; un diagnostic expurgé en développement est plus utile qu’une trace technique dans l’interface.
Respecter ce que le visiteur veut copier
Le comportement de copie dépend du résultat :
| Résultat | Comportement de copie | Point à surveiller |
|---|---|---|
| Texte échappé en HTML | Copier les entités telles que & | Ne pas décoder automatiquement sans choix du mode Décoder |
| URL ou valeur de paramètre | Copier exactement l’encodage vérifié | Reconstruire une URL signée peut invalider sa signature |
| Commande cURL | Préserver les guillemets, espaces, barres obliques inverses et sauts de ligne | Signaler la présence éventuelle d’identifiants |
| Mot de passe ou phrase de passe | Copier exactement la valeur choisie | L’historique du presse-papiers et d’autres applications peuvent la conserver |
| Lien de partage d’avatar | Copier le lien, pas une approximation de l’image | Le lien peut reconstruire un personnage sans figer un PNG |
L’encodeur d’URL et éditeur de paramètres rappelle qu’un signe plus littéral et une espace peuvent avoir des significations différentes. Copier une chaîne de paramètres normalisée n’est approprié qu’après vérification par le visiteur. Pour un exemple de personnalisation que l’on peut copier et partager, consultez Découvrez notre nouveau générateur d’avatar.
Si un résultat propose les actions “Copier” et “Télécharger”, présentez-les comme deux opérations distinctes. Télécharger un fichier texte n’est pas un recours approprié pour copier un secret si cela crée inutilement une copie non chiffrée sur le disque.
Protéger les identifiants lors de la copie
Les générateurs de mots de passe et de fichiers htpasswd méritent une attention particulière. Des applications ou extensions disposant des autorisations ou accès suffisants peuvent lire le presse-papiers. Les systèmes d’exploitation peuvent aussi conserver son historique ou le synchroniser entre appareils. Un navigateur peut confirmer la copie d’un texte ; il ne peut pas garantir ce qu’il en advient ensuite.
Si votre application manipule des secrets, envisagez ces précautions :
- Excluez les secrets des événements de mesure d’audience, des URL et des rapports d’erreur.
- Ne consignez pas le texte copié dans la console.
- Expliquez qu’un mot de passe copié doit être conservé dans un gestionnaire de mots de passe et que l’historique du presse-papiers peut le retenir.
- Évitez de vider automatiquement le presse-papiers après un délai. Cette opération n’est pas fiable dans tous les navigateurs et peut remplacer un autre élément copié entre-temps.
- Pour les usages très sensibles, prévoyez un autre moyen de révéler ou de transférer la valeur si la copie est bloquée.
Le générateur de mots de passe et de phrases de passe et le générateur htpasswd de Web2Generators illustrent l’intérêt d’une copie bien pensée : le secret et la configuration serveur qui en découle sont des données différentes. L’utilisateur doit comprendre ce qu’il transfère.
Vérifier l’accessibilité dans les situations difficiles
Un clic de souris réussi sur ordinateur ne suffit pas. Essayez le bouton avec Tab et Entrée ou Espace. L’indicateur de focus doit rester visible, l’annonce doit être compréhensible et un échec ne doit pas bloquer la navigation au clavier. Vérifiez le zoom à 200 %, les écrans mobiles étroits et les longs résultats qui défilent horizontalement.
Si vous désactivez temporairement le bouton pendant la copie, indiquez visiblement qu’une opération est en cours et réactivez-le après un succès comme après un échec. Désactiver un bouton pour une opération presque instantanée présente généralement peu d’intérêt.
Testez aussi avec un lecteur d’écran, notamment les succès et échecs répétés : effacer puis réinsérer rapidement le même message peut ne pas déclencher une nouvelle annonce.
Utilisez les outils d’inspection de l’accessibilité du navigateur pour vérifier le nom accessible du bouton et la zone de statut. Dans une page comportant plusieurs générateurs, gardez les messages près du résultat concerné. Une notification globale à l’autre bout de l’écran peut passer inaperçue.
Vérifier les données envoyées sur le réseau
L’API Clipboard écrit dans le presse-papiers du système local ; elle n’ordonne pas, à elle seule, d’envoyer une requête à votre serveur. Le code de l’application peut néanmoins effectuer des requêtes lors d’un clic. Si votre outil promet un traitement local, vérifiez-le avec des données d’exemple sans risque.
Ouvrez le panneau Réseau, retirez les filtres, utilisez le bouton de copie et inspectez les nouvelles requêtes. Le guide d’inspection des requêtes réseau de Web2Generators explique cette méthode et ses limites. L’absence de requêtes lors d’un essai fournit un indice utile, mais aucune garantie absolue de confidentialité.
Une implémentation sûre distingue également l’échappement du résultat de sa copie. Dans un aperçu HTML, utilisez textContent pour afficher du texte brut ou appliquez un modèle d’assainissement adapté au texte enrichi accepté. L’article sur l’échappement et l’assainissement HTML explique ce choix. N’utilisez pas innerHTML pour insérer du texte arbitraire simplement afin de le rendre copiable.
Quelques essais avant la mise en ligne
Essayez un mot court, une commande shell sur plusieurs lignes, des guillemets, une esperluette, une URL contenant %2B et un long résultat. Collez dans un éditeur de texte brut et vérifiez les caractères et sauts de ligne attendus, en tenant compte des conventions du système d’exploitation. Utilisez des valeurs d’exemple sans risque. Testez dans un navigateur pris en charge avec HTTPS, puis dans un environnement volontairement restreint où la copie automatique échoue. Enfin, essayez une page avec deux boutons de copie pour vérifier que chacun copie le bon résultat et annonce son propre statut.
À essayer : créez une requête d’exemple avec le générateur de commandes cURL de Web2Generators et vérifiez le comportement de la commande copiée dans votre éditeur ou terminal.