Bindings
Call Go functions from JavaScript.
Wails provides a unified clipboard API that works across all platforms. Copy and paste text with simple, consistent methods on Windows, macOS, and Linux.
// Copy text to clipboardapp.Clipboard.SetText("Hello, World!")
// Get text from clipboardtext, ok := app.Clipboard.Text()if ok { fmt.Println("Clipboard:", text)}That’s it! Cross-platform clipboard access.
success := app.Clipboard.SetText("Text to copy")if !success { app.Logger.Error("Failed to copy to clipboard")}Returns: bool - true if successful, false otherwise
type ClipboardService struct { app *application.Application}
func (c *ClipboardService) CopyToClipboard(text string) bool { return c.app.Clipboard.SetText(text)}Call from JavaScript:
import { CopyToClipboard } from './bindings/myapp/clipboardservice'
await CopyToClipboard("Text to copy")func copyWithFeedback(text string) { if app.Clipboard.SetText(text) { app.Dialog.Info(). SetTitle("Copied"). SetMessage("Text copied to clipboard!"). Show() } else { app.Dialog.Error(). SetTitle("Copy Failed"). SetMessage("Failed to copy to clipboard."). Show() }}text, ok := app.Clipboard.Text()if !ok { app.Logger.Error("Failed to read clipboard") return}
fmt.Println("Clipboard text:", text)Returns: (string, bool) - Text and success flag
func (c *ClipboardService) PasteFromClipboard() string { text, ok := c.app.Clipboard.Text() if !ok { return "" } return text}Call from JavaScript:
import { PasteFromClipboard } from './bindings/myapp/clipboardservice'
const text = await PasteFromClipboard()console.log("Pasted:", text)func pasteText() (string, error) { text, ok := app.Clipboard.Text() if !ok { return "", errors.New("clipboard empty or unavailable") }
// Validate if len(text) == 0 { return "", errors.New("clipboard is empty") }
if len(text) > 10000 { return "", errors.New("clipboard text too large") }
return text, nil}Go:
type TextService struct { app *application.Application}
func (t *TextService) CopyText(text string) error { if !t.app.Clipboard.SetText(text) { return errors.New("failed to copy") } return nil}JavaScript:
import { CopyText } from './bindings/myapp/textservice'
async function copyToClipboard(text) { try { await CopyText(text) showNotification("Copied to clipboard!") } catch (error) { showError("Failed to copy: " + error) }}
// Usagedocument.getElementById('copy-btn').addEventListener('click', () => { const text = document.getElementById('text').value copyToClipboard(text)})Go:
type DataService struct { app *application.Application}
func (d *DataService) PasteAndProcess() (string, error) { // Get clipboard text text, ok := d.app.Clipboard.Text() if !ok { return "", errors.New("clipboard unavailable") }
// Process text processed := strings.TrimSpace(text) processed = strings.ToUpper(processed)
return processed, nil}JavaScript:
import { PasteAndProcess } from './bindings/myapp/dataservice'
async function pasteAndProcess() { try { const result = await PasteAndProcess() document.getElementById('output').value = result } catch (error) { showError("Failed to paste: " + error) }}type CopyService struct { app *application.Application}
func (c *CopyService) CopyAsPlainText(text string) bool { return c.app.Clipboard.SetText(text)}
func (c *CopyService) CopyAsJSON(data interface{}) bool { jsonBytes, err := json.MarshalIndent(data, "", " ") if err != nil { return false } return c.app.Clipboard.SetText(string(jsonBytes))}
func (c *CopyService) CopyAsCSV(rows [][]string) bool { var buf bytes.Buffer writer := csv.NewWriter(&buf)
for _, row := range rows { if err := writer.Write(row); err != nil { return false } }
writer.Flush() return c.app.Clipboard.SetText(buf.String())}type ClipboardMonitor struct { app *application.Application lastText string ticker *time.Ticker stopChan chan bool}
func NewClipboardMonitor(app *application.Application) *ClipboardMonitor { return &ClipboardMonitor{ app: app, stopChan: make(chan bool), }}
func (cm *ClipboardMonitor) Start() { cm.ticker = time.NewTicker(1 * time.Second)
go func() { for { select { case <-cm.ticker.C: cm.checkClipboard() case <-cm.stopChan: return } } }()}
func (cm *ClipboardMonitor) Stop() { if cm.ticker != nil { cm.ticker.Stop() } cm.stopChan <- true}
func (cm *ClipboardMonitor) checkClipboard() { text, ok := cm.app.Clipboard.Text() if !ok { return }
if text != cm.lastText { cm.lastText = text cm.app.Event.Emit("clipboard-changed", text) }}type ClipboardHistory struct { app *application.Application history []string maxSize int}
func NewClipboardHistory(app *application.Application) *ClipboardHistory { return &ClipboardHistory{ app: app, history: make([]string, 0), maxSize: 10, }}
func (ch *ClipboardHistory) Copy(text string) bool { if !ch.app.Clipboard.SetText(text) { return false }
// Add to history ch.history = append([]string{text}, ch.history...)
// Limit size if len(ch.history) > ch.maxSize { ch.history = ch.history[:ch.maxSize] }
return true}
func (ch *ClipboardHistory) GetHistory() []string { return ch.history}
func (ch *ClipboardHistory) RestoreFromHistory(index int) bool { if index < 0 || index >= len(ch.history) { return false }
return ch.app.Clipboard.SetText(ch.history[index])}For simple text, you can use the browser’s clipboard API:
// Copyasync function copyText(text) { try { await navigator.clipboard.writeText(text) console.log("Copied!") } catch (error) { console.error("Copy failed:", error) }}
// Pasteasync function pasteText() { try { const text = await navigator.clipboard.readText() return text } catch (error) { console.error("Paste failed:", error) return "" }}Note: Browser clipboard API requires HTTPS or localhost, and user permission.
For system-wide clipboard access:
import { CopyToClipboard, PasteFromClipboard } from './bindings/myapp/clipboardservice'
// Copyasync function copy(text) { const success = await CopyToClipboard(text) if (success) { console.log("Copied!") }}
// Pasteasync function paste() { const text = await PasteFromClipboard() return text}Bindings
Call Go functions from JavaScript.
Events
Use events for clipboard notifications.
dialogs
Show copy/paste feedback.
Services
Organise clipboard code.
Questions? Ask in Discord or check the clipboard examples.