mdawar.dev

A blog about programming, Web development, Open Source, Linux and DevOps.

Copy to Clipboard in the Browser

Copy to clipboard function with a fallback method for browsers that don’t support Clipboard.writeText() function.

JavaScript

js
/**
 * Copy text to the clipboard.
 *
 * @param text - Text to copy to the clipboard.
 * @returns void
 */
function copyToClipboard(text) {
  const { clipboard } = window.navigator;

  if (typeof clipboard?.writeText !== 'function') {
    return copyToClipboardFallback(text);
  }

  return clipboard.writeText(text);
}

/**
 * Fallback method to copy text to the clipboard.
 *
 * To be used for browsers that don't support `Clipboard.writeText`.
 *
 * @param text - Text to copy to the clipboard.
 * @returns void
 */
function copyToClipboardFallback(text) {
  const textArea = document.createElement('textarea');
  textArea.value = text;

  // Prevent scroll to bottom after appendChild
  textArea.style.position = 'fixed';
  textArea.style.top = '0';
  textArea.style.left = '-9999px';

  document.body.appendChild(textArea);
  textArea.focus();
  textArea.select();

  try {
    const success = document.execCommand('copy');

    if (success) {
      return Promise.resolve();
    } else {
      throw new Error('Failed to copy to the clipboard');
    }
  } catch (err) {
    return Promise.reject(err);
  } finally {
    document.body.removeChild(textArea);
  }
}

TypeScript

ts
/**
 * Copy text to the clipboard.
 *
 * @param text - Text to copy to the clipboard.
 * @returns void
 */
function copyToClipboard(text: string): Promise<void> {
  const { clipboard } = window.navigator;

  if (typeof clipboard?.writeText !== 'function') {
    return copyToClipboardFallback(text);
  }

  return clipboard.writeText(text);
}

/**
 * Fallback method to copy text to the clipboard.
 *
 * To be used for browsers that don't support `Clipboard.writeText`.
 *
 * @param text - Text to copy to the clipboard.
 * @returns void
 */
function copyToClipboardFallback(text: string): Promise<void> {
  const textArea = document.createElement('textarea');
  textArea.value = text;

  // Prevent scroll to bottom after appendChild
  textArea.style.position = 'fixed';
  textArea.style.top = '0';
  textArea.style.left = '-9999px';

  document.body.appendChild(textArea);
  textArea.focus();
  textArea.select();

  try {
    const success = document.execCommand('copy');

    if (success) {
      return Promise.resolve();
    } else {
      throw new Error('Failed to copy to the clipboard');
    }
  } catch (err) {
    return Promise.reject(err);
  } finally {
    document.body.removeChild(textArea);
  }
}