The clipboard-manager plugin provides comprehensive clipboard operations for your Tauri application, allowing you to read from and write to the system clipboard with enhanced functionality.
{
"plugins": {
"clipboard-manager": {
"all": true
}
}
}- all: Grants all clipboard permissions (read and write)
- Alternatively, you can specify individual permissions:
{ "clipboard-manager": { "read": true, "write": true } }
[dependencies]
tauri-plugin-clipboard-manager = "2.0"use tauri_plugin_clipboard_manager::ClipboardExt;
#[tauri::command]
pub async fn copy_to_clipboard(app: tauri::AppHandle, text: String) -> Result<(), String> {
app.clipboard()
.write_text(text)
.map_err(|e| format!("Failed to copy to clipboard: {}", e))
}
#[tauri::command]
pub async fn paste_from_clipboard(app: tauri::AppHandle) -> Result<String, String> {
app.clipboard()
.read_text()
.map_err(|e| format!("Failed to read from clipboard: {}", e))
.and_then(|opt| opt.ok_or_else(|| "Clipboard is empty".to_string()))
}
#[tauri::command]
pub async fn get_clipboard_history(app: tauri::AppHandle) -> Result<Vec<String>, String> {
// Note: Basic clipboard plugin doesn't provide history by default
// This example shows current clipboard content
match app.clipboard().read_text() {
Ok(Some(content)) => Ok(vec![content]),
Ok(None) => Ok(vec![]),
Err(e) => Err(format!("Failed to get clipboard history: {}", e)),
}
}
#[tauri::command]
pub async fn clear_clipboard(app: tauri::AppHandle) -> Result<(), String> {
app.clipboard()
.write_text("")
.map_err(|e| format!("Failed to clear clipboard: {}", e))
}import { invoke } from '@tauri-apps/api/core'
// Copy text to clipboard
async function copyToClipboard(text: string): Promise<void> {
try {
await invoke('copy_to_clipboard', { text })
console.log('Text copied to clipboard successfully')
} catch (error) {
console.error('Failed to copy text to clipboard:', error)
throw error
}
}
// Paste text from clipboard
async function pasteFromClipboard(): Promise<string> {
try {
const text = await invoke('paste_from_clipboard')
console.log('Text pasted from clipboard:', text)
return text as string
} catch (error) {
console.error('Failed to paste from clipboard:', error)
throw error
}
}
// Get clipboard content (basic history)
async function getClipboardHistory(): Promise<string[]> {
try {
const history = await invoke('get_clipboard_history')
return history as string[]
} catch (error) {
console.error('Failed to get clipboard history:', error)
throw error
}
}
// Clear clipboard
async function clearClipboard(): Promise<void> {
try {
await invoke('clear_clipboard')
console.log('Clipboard cleared successfully')
} catch (error) {
console.error('Failed to clear clipboard:', error)
throw error
}
}import { useState, useCallback } from 'react'
interface UseClipboardReturn {
clipboardText: string
copyToClipboard: (text: string) => Promise<void>
pasteFromClipboard: () => Promise<string>
clearClipboard: () => Promise<void>
isLoading: boolean
error: string | null
}
export function useClipboard(): UseClipboardReturn {
const [clipboardText, setClipboardText] = useState('')
const [isLoading, setIsLoading] = useState(false)
const [error, setError] = useState<string | null>(null)
const copyToClipboard = useCallback(async (text: string) => {
setIsLoading(true)
setError(null)
try {
await invoke('copy_to_clipboard', { text })
setClipboardText(text)
} catch (err) {
setError(err as string)
throw err
} finally {
setIsLoading(false)
}
}, [])
const pasteFromClipboard = useCallback(async () => {
setIsLoading(true)
setError(null)
try {
const text = await invoke('paste_from_clipboard') as string
setClipboardText(text)
return text
} catch (err) {
setError(err as string)
throw err
} finally {
setIsLoading(false)
}
}, [])
const clearClipboard = useCallback(async () => {
setIsLoading(true)
setError(null)
try {
await invoke('clear_clipboard')
setClipboardText('')
} catch (err) {
setError(err as string)
throw err
} finally {
setIsLoading(false)
}
}, [])
return {
clipboardText,
copyToClipboard,
pasteFromClipboard,
clearClipboard,
isLoading,
error
}
}// Monitor clipboard changes (requires periodic polling)
class ClipboardMonitor {
private lastContent: string = ''
private intervalId: NodeJS.Timeout | null = null
private callbacks: Array<(content: string) => void> = []
start(intervalMs: number = 1000) {
this.intervalId = setInterval(async () => {
try {
const currentContent = await invoke('paste_from_clipboard') as string
if (currentContent !== this.lastContent) {
this.lastContent = currentContent
this.callbacks.forEach(callback => callback(currentContent))
}
} catch (error) {
// Clipboard might be empty or inaccessible
}
}, intervalMs)
}
stop() {
if (this.intervalId) {
clearInterval(this.intervalId)
this.intervalId = null
}
}
onChange(callback: (content: string) => void) {
this.callbacks.push(callback)
return () => {
const index = this.callbacks.indexOf(callback)
if (index > -1) {
this.callbacks.splice(index, 1)
}
}
}
}
// Usage
const clipboardMonitor = new ClipboardMonitor()
clipboardMonitor.onChange((content) => {
console.log('Clipboard changed:', content)
})
clipboardMonitor.start(500) // Check every 500ms// Copy selected text
async function copySelection() {
const selection = window.getSelection()?.toString()
if (selection) {
await copyToClipboard(selection)
}
}
// Paste at cursor position
async function pasteAtCursor(textArea: HTMLTextAreaElement) {
try {
const text = await pasteFromClipboard()
const start = textArea.selectionStart
const end = textArea.selectionEnd
const currentValue = textArea.value
textArea.value = currentValue.slice(0, start) + text + currentValue.slice(end)
textArea.selectionStart = textArea.selectionEnd = start + text.length
} catch (error) {
console.error('Failed to paste:', error)
}
}// Copy structured data as JSON
async function copyData(data: any) {
const jsonString = JSON.stringify(data, null, 2)
await copyToClipboard(jsonString)
}
// Paste and parse structured data
async function pasteData<T>(): Promise<T> {
const text = await pasteFromClipboard()
try {
return JSON.parse(text) as T
} catch (error) {
throw new Error('Invalid JSON in clipboard')
}
}- Sensitive Data: Be cautious when copying sensitive information like passwords or API keys
- Data Validation: Always validate clipboard content before processing
- User Consent: Consider asking for user permission before accessing clipboard
- Rate Limiting: Implement rate limiting for frequent clipboard operations
- Privacy: Avoid logging clipboard content for privacy reasons
- Supports text, HTML, and image formats
- Rich text formatting is preserved
- Some operations may require elevated permissions
- Excellent clipboard integration
- Supports multiple data types simultaneously
- Pasteboard system provides robust functionality
- X11 vs Wayland differences
- Multiple clipboard selections (primary, secondary, clipboard)
- May require additional permissions in some distributions
- Ensure
clipboard-managerplugin is properly configured - Check app permissions on the target platform
- Verify the plugin is included in the build
- Handle empty clipboard gracefully in your application
- Provide user feedback when clipboard operations fail
- Consider default values for paste operations
- Be aware of clipboard size limitations on different platforms
- Implement chunking for very large content
- Consider alternative data transfer methods for large files
- Some applications may not release clipboard properly
- Test clipboard operations with various source applications
- Implement retry logic for failed operations