Tauri Plugin clipboard
A Tauri plugin for clipboard read/write/monitor. Support text, files and image.
The reason I built this plugin is becasue official Tauri API only supports clipboard with text, not image or files. So you can still use the official API for text.
Installation
If you are installing from npm and crate.io package registry, make sure the versions for both packages are the same, otherwise, the API may not match.
Crate: https://crates.io/crates/tauri-plugin-clipboard
cargo add tauri-plugin-clipboard to add the package.
Or add the following to your Cargo.toml for the latest unpublished version (not recommanded).
= { = "https://github.com/CrossCopy/tauri-plugin-clipboard" }
You can also add a tag to github url.
= { = "https://github.com/CrossCopy/tauri-plugin-clipboard", = "v0.5.0" }
NPM Package: https://www.npmjs.com/package/tauri-plugin-clipboard-api
Run the following to install JavaScript/TypeScript API package.
# npm add https://github.com/CrossCopy/tauri-plugin-clipboard # or this for latest unpublished version (not recommended)
In main.rs, add the following to your tauri::Builder:
default
.plugin
.run
.expect;
Read more in the official doc about how to use.
Example
The best way to learn this plugin is to read the source code of the example.
The example is very detailed.

# there are a few buttons you can click to test the clipboard plugin
See App.svelte for an example of how to use the plugin in JS/TS.
It works the same with other frontend frameworks like Vue, React, etc.
Sample Usage (TypeScript API)
import {
readText,
readFiles,
writeText,
readImage,
readImageBinary,
readImageObjectURL,
writeImage,
} from "tauri-plugin-clipboard-api";
await readText();
await writeText("huakun zui shuai");
readImage()
.then((base64Img) => {
imageStr = `data:image/png;base64, ${base64Img}`;
})
.catch((err) => {
alert(err);
});
await writeImage(sample_base64_image);
const files: string[] = await readFiles();
Sample Usage (Rust API)
ClipboardManager contains the state state as well as the API functions.
use Manager;
use ManagerExt;
Sample Listener Usage
We use Tauri's event system. Start a listener with Tauri's listen() function to start listening for event, and call listenImage() and listenText() to listen for clipboard update. When clipboard is updated, event will be emitted.
The following example is in svelte.
import type { UnlistenFn } from "@tauri-apps/api/event";
import { onDestroy, onMount } from "svelte";
import {
onClipboardUpdate,
onImageUpdate,
onTextUpdate,
onFilesUpdate,
startListening,
listenToMonitorStatusUpdate,
isMonitorRunning,
} from "tauri-plugin-clipboard-api";
let text = "";
let files: string[] = [];
let base64Image = "";
let monitorRunning = false;
let unlistenTextUpdate: UnlistenFn;
let unlistenImageUpdate: UnlistenFn;
let unlistenClipboard: () => Promise<void>;
let unlistenFiles: UnlistenFn;
onMount(async () => {
unlistenTextUpdate = await onTextUpdate((newText) => {
text = newText;
});
unlistenImageUpdate = await onImageUpdate((b64Str) => {
base64Image = b64Str;
});
unlistenFiles = await onFilesUpdate((newFiles) => {
files = newFiles;
});
unlistenClipboard = await startListening();
onClipboardUpdate(() => {
console.log("plugin:clipboard://clipboard-monitor/update event received");
});
});
listenToMonitorStatusUpdate((running) => {
monitorRunning = running;
});
onDestroy(() => {
unlistenTextUpdate();
unlistenImageUpdate();
unlistenClipboard();
unlistenFiles();
});
Notes
You don't really need to read this section if you are just using the plugin.
The logic of tauri's listen API is encapsulated in onTextUpdate, onFilesUpdate, startListening.
You can also listen to the events directly using Tauri's listen() function.
import {
TEXT_CHANGED,
FILES_CHANGED,
IMAGE_CHANGED,
} from "tauri-plugin-clipboard-api";
await listen(TEXT_CHANGED, (event) => {
const text = event.payload.value;
});
The listener startListening function contains two parts:
- Start monitor thread in Tauri core (rust). (Invoke
start_monitorcommand) - Run
listenToClipboardfunction.- The rust code only emit event (
plugin:clipboard://clipboard-monitor/update) when clipboard is updated without the clipboard content because we don't always need the content. - In order to distinguish content type,
listenToClipboarddetects the data type and emit new events.onTextUpdate,onFilesUpdate,startListeninglisten to these events.plugin:clipboard://text-changedplugin:clipboard://files-changedplugin:clipboard://image-changed
- The rust code only emit event (
The returned unlisten function from startListening also does two things:
- Stop monitor thread by invoking
start_monitorcommand. - Stop listener started in
listenToClipboard.
The base64 image string can be converted to Uint8Array and written to file system using tauri's fs API.
import { writeBinaryFile, BaseDirectory } from "@tauri-apps/api/fs";
writeBinaryFile(
"tmp/avatar.png",
new Uint8Array(
atob(base64Img)
.split("")
.map((char) => char.charCodeAt(0))
),
{ dir: BaseDirectory.Cache }
);