Yevhen Klymentiev
dark
light
console
darkness
y.klymentiev@gmail.com
Reusable Snippets|Practical utility code for everyday use — custom-built and ready to share

copyToClipboard

Copies text to the system clipboard.

TypeScript
Copied!
1/**
2 * Copies text to the system clipboard.
3 *
4 * @param text - The text to copy.
5 * @returns A promise that resolves if the copy is successful.
6 */
7export async function copyToClipboard(text: string): Promise<void> {
8  if (navigator.clipboard && navigator.clipboard.writeText) {
9    return navigator.clipboard.writeText(text);
10  }
11
12  // Fallback for older browsers
13  const textarea = document.createElement('textarea');
14  textarea.value = text;
15  textarea.setAttribute('readonly', '');
16  textarea.style.position = 'absolute';
17  textarea.style.left = '-9999px';
18
19  document.body.appendChild(textarea);
20  textarea.select();
21
22  try {
23    document.execCommand('copy');
24  } finally {
25    document.body.removeChild(textarea);
26  }
27}
  • Modern Clipboard API Support

    Utilizes the native navigator.clipboard.writeText method when available for secure, async clipboard access.

  • Robust Fallback Mechanism

    Includes a backward-compatible fallback using document.execCommand('copy'), ensuring broader browser support.

  • No External Dependencies

    Implements copy functionality with vanilla JavaScript, avoiding reliance on third-party libraries.

  • Encapsulated and Safe

    Automatically cleans up the DOM after fallback use, preventing memory leaks or stray elements.

Tests | Examples

TypeScript
Copied!
1beforeEach(() => {
2  jest.restoreAllMocks();
3});
4
5test('uses navigator.clipboard if available', async () => {
6  const mockWriteText = jest.fn().mockResolvedValue(undefined);
7  Object.assign(navigator, {
8    clipboard: {
9      writeText: mockWriteText,
10    },
11  });
12
13  await copyToClipboard('Hello');
14  expect(mockWriteText).toHaveBeenCalledWith('Hello');
15});
16
17test('falls back to execCommand if clipboard API not available', async () => {
18  delete (navigator as any).clipboard;
19
20  const execCommandSpy = jest
21    .spyOn(document, 'execCommand')
22    .mockImplementation(() => true);
23
24  const appendSpy = jest.spyOn(document.body, 'appendChild');
25  const removeSpy = jest.spyOn(document.body, 'removeChild');
26
27  await copyToClipboard('Fallback');
28
29  expect(execCommandSpy).toHaveBeenCalledWith('copy');
30  expect(appendSpy).toHaveBeenCalled();
31  expect(removeSpy).toHaveBeenCalled();
32});

Common Use Cases

  • "Copy to Clipboard" Buttons

    Enable users to quickly copy text like promo codes, reference IDs, or links.

  • Code Snippet Sharing

    Provide convenient copy functionality in documentation or dev tools.

  • Clipboard Integration in Forms

    Allow users to copy form data or generated passwords for reuse elsewhere.

  • Interactive Tutorials or Onboarding

    Offer pre-filled commands or URLs that users can easily copy with one click.

  • Fallback for Non-Secure Contexts

    Ensure reliable copying even in older browsers or non-HTTPS environments.

Codebase: Utilities -> Browser & DOM -> copyToClipboard | Yevhen Klymentiev