Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Cross-Environment Clipboard Copy Implementation for Vue

Tech 1

Bind a click handler to your target element, passing the text string you want to duplicate during invocation.

Clipboard API Overview

The modern navigator.clipboard API provides a promise-based, secure way to interact with system clipboard data:

Method Purpose
read() Retrieves arbitrary clipboard content (supports images, files, text)
readText() Fetches plain text content exclusively from the system clipboard
write() Writes mixed data types (text, images) to the system clipboard
writeText() Simplifies plain text clipboard insertion with a single call

Initial Plain Text Copy Function

async function performTextCopy(targetText) {
  return await navigator.clipboard.writeText(targetText);
}

Comon Deployment Error

After local HTTPS/localhost testing, many teams encounter this issue on internal IP staging environments:

TypeError: Cannot read properties of undefined (reading 'writeText')

Root Cause Analysis

The navigator.clipboard API is restricted to secure contexts — pages served over HTTPS, localhost, or file:// URLs in some browsers. Internal IP addresses (like http://192.168.1.100) fall out side this scope, disabling the API entirely.

Compatibility-First Fix

Combine secure context detection with a fallback to the deprecated but widely supported document.execCommand('copy') method:

  1. Check for valid navigator.clipboard and active secure context
  2. Use the modern API first for better performance and security
  3. Fall back to a temporary off-screen <textarea> element when needeed
import { ElMessage } from 'element-plus'; // Replace with your UI library toast

async function duplicateLink(linkValue) {
  if (navigator.clipboard && window.isSecureContext) {
    try {
      await navigator.clipboard.writeText(linkValue);
      ElMessage.success('Link copied to clipboard!');
      return true;
    } catch (err) {
      console.error('Secure clipboard copy failed:', err);
    }
  }

  // Fallback for non-secure contexts
  const tempInput = document.createElement('textarea');
  tempInput.value = linkValue;
  tempInput.style.position = 'absolute';
  tempInput.style.left = '-9999px';
  tempInput.style.top = '-9999px';
  tempInput.setAttribute('readonly', '');
  document.body.appendChild(tempInput);
  tempInput.focus();
  tempInput.select();
  tempInput.setSelectionRange(0, tempInput.value.length);

  try {
    const copySuccess = document.execCommand('copy');
    if (copySuccess) {
      ElMessage.success('Link copied to clipboard!');
    } else {
      ElMessage.error('Copy failed. Please select and copy manually.');
    }
    return copySuccess;
  } catch (fallbackErr) {
    console.error('Fallback copy method failed:', fallbackErr);
    ElMessage.error('Copy failed. Please select and copy manually.');
    return false;
  } finally {
    document.body.removeChild(tempInput);
  }
}

Quick Reference for document.execCommand

While deprecated, document.execCommand still works across most browsers for basic text operations. It accepts three parameters:

  • commandId: String identifier for the desired action
  • showUI: Boolean to enable/disable native dialogs
  • valueArgument: Optional dynamic input for commands requiring it

Basic Action Examples

<input type="button" value="Cut Selection" onclick="document.execCommand('Cut')">
<input type="button" value="Copy Selected" onclick="document.execCommand('Copy')">
<input type="button" value="Paste Content" onclick="document.execCommand('Paste')">
<input type="button" value="Undo Last Edit" onclick="document.execCommand('Undo')">
<input type="button" value="Delete Highlighted" onclick="document.execCommand('Delete')">
<input type="button" value="Toggle Bold" onclick="document.execCommand('Bold')">
<input type="button" value="Toggle Italic" onclick="document.execCommand('Italic')">
<input type="button" value="Toggle Underline" onclick="document.execCommand('Underline')">
<input type="button" value="Stop Page Load" onclick="document.execCommand('stop')">
<input type="button" value="Save Page" onclick="document.execCommand('SaveAs')">

Reusable Helper Functions

// Copy from a specific text area
function copyFromEditor(editorId) {
  const editor = document.getElementById(editorId);
  if (!editor) return;
  editor.select();
  document.execCommand('Copy');
}

// Paste into a target input
function pasteToTarget(targetId) {
  const target = document.getElementById(targetId);
  if (!target) return;
  target.focus();
  document.execCommand('Paste');
}

// Create hyperlink with custom URL
function addCustomHyperlink(url = 'https://example.com') {
  document.execCommand('CreateLink', false, url);
}

// Change selected text foreground color
function setTextColor(colorCode) {
  document.execCommand('ForeColor', false, colorCode);
}

// Toggle ordered/unordered lists
function toggleList(listType = 'InsertUnorderedList') {
  document.execCommand(listType);
}

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.