Implementing Cross-Device Copy-Paste in Mobile Applications
Copy text on phone, paste on laptop. Simple in concept, but implementation hits clipboard limitations on both platforms and requires a server component. Native universal clipboard (Apple Universal Clipboard) works only within the Apple ecosystem with Handoff enabled. For cross-platform scenarios (iOS → Android, mobile → desktop), a different approach is needed.
Apple Universal Clipboard: When It Works Automatically
If both devices are Apple, use the same Apple ID, and Handoff is enabled, UIPasteboard.general on iOS automatically syncs through iCloud. No implementation needed. But this only works for text and images with 30–60 second delay, and only within Apple ecosystem.
For apps that must work platform-agnostically, build your own mechanism.
Cross-Device Clipboard Architecture
Minimal schema: server stores user clipboard, clients sync via WebSocket or polling.
// Server-side: simple storage with TTL
type ClipboardEntry = {
userId: string;
content: string;
contentType: 'text' | 'image' | 'file';
mimeType?: string;
expiresAt: number; // unix timestamp
deviceId: string; // source device
};
TTL is mandatory. Clipboard shouldn't store data forever: sensitive information (passwords, tokens, card data) that users copy should be deleted. 30–120 minutes is reasonable TTL for most scenarios.
Native Clipboard in React Native
import Clipboard from '@react-native-clipboard/clipboard';
// Copy with server sync
const copyToCloudClipboard = async (text: string) => {
// First to local clipboard — instant
await Clipboard.setString(text);
// Parallel server sync
await api.clipboard.push({
content: text,
contentType: 'text',
deviceId: getDeviceId(),
});
};
// Paste: check cloud clipboard first
const pasteFromCloudClipboard = async (): Promise<string> => {
const [localContent, cloudEntry] = await Promise.all([
Clipboard.getString(),
api.clipboard.getLatest(),
]);
// Choose fresher
if (cloudEntry && cloudEntry.updatedAt > localTimestamp) {
return cloudEntry.content;
}
return localContent;
};
Content Beyond Text
Images: upload to S3/CDN, store only URL + metadata in clipboard. Image size in clipboard—up to 10 MB, enforce limit on client. Files: similar, download URL.
On iOS, UIPasteboard supports types via UTType. When copying images to native apps, use a native module reading UIPasteboard.general.image and uploading to cloud clipboard. @react-native-clipboard/clipboard baseline doesn't support images—patch or write native module.
Notification on New Clipboard Content
Push notification when new content appears in clipboard—bad UX: user just copied it, why notify? Better: UI indicator on app open or silent sync via background fetch.
WebSocket approach: on app open, subscribe to user channel. When new clipboard content arrives from another device, show non-blocking banner "Copied from MacBook: "text..."".
Security: What Shouldn't Go to Cloud Clipboard
Detect sensitive content before sending to server:
- Regex for card numbers (Luhn validation): don't send, clear after 30 sec.
- Regex for passwords in format
password: xyz—don't send. - Very long strings (>100 KB)—likely not meant for clipboard.
Encryption: encrypt clipboard content with key derived from user password or device key. Server stores encrypted blob—can't read contents.
Estimate
Cross-device clipboard (text + images) with E2E encryption, WebSocket notifications, and TTL: 3–5 weeks.







