Vue 3 Clipboard Composition API
vue-clipboard3 is a Vue 3 Composition API utility for easily copying text to the clipboard. Currently at version 2.0.0, it provides a simple `useClipboard` hook that leverages `clipboard.js` internally to handle the complexities of cross-browser clipboard access. The package follows a lightweight approach, foregoing directives in favor of a direct method call within the `setup()` function, aligning with Vue 3's modern Composition API patterns. Its release cadence has been responsive, with recent updates focused on compatibility with modern build tools like Vite and ESM module standards. This library differentiates itself by offering a clean, hook-based API for Vue 3 projects that require clipboard functionality without the overhead of older directive-based solutions, ensuring a straightforward and explicit developer experience.
Common errors
-
Cannot use import statement outside a module
cause Attempting to use `vue-clipboard3` (v2.0.0+) in a CommonJS environment or a project not configured for ESM module resolution.fixEnsure your project's `package.json` has `"type": "module"`, or configure your bundler (e.g., Webpack, Rollup, Vite) to correctly handle ESM imports. Migrate `require()` calls to `import` statements. -
TypeError: useClipboard is not a function
cause Incorrect import of the `useClipboard` hook, likely attempting a named import when it's a default export, or using `require()` after v2.0.0.fixChange the import statement to `import useClipboard from 'vue-clipboard3';` to correctly import the default export. -
Uncaught (in promise) DOMException: The request is not allowed by the user agent or the platform in the current context.
cause The browser or platform denied the clipboard write operation, often due to security restrictions, lack of user gesture (e.g., not triggered by a click event), or clipboard permissions.fixEnsure `toClipboard` is called in response to a direct user action (like a button click). Provide robust `try...catch` blocks to inform the user if copying fails and consider adding an option for the user to manually copy the text if automatic copying is prevented.
Warnings
- breaking Version 2.0.0 transitioned the package to be ESM-only. Projects relying on CommonJS `require()` or older build configurations (e.g., Webpack 4 without proper ESM handling) will encounter errors like 'Cannot use import statement outside a module'.
- gotcha Unlike some older Vue clipboard libraries (e.g., `vue-clipboard2`), `vue-clipboard3` does not provide a directive. It is intended for use directly within the `setup()` function as a Composition API hook. Attempting to use it as a `v-clipboard` directive will not work.
- gotcha The `toClipboard` function returns a Promise. It is crucial to `await` its execution and include proper `try...catch` error handling to manage potential failures (e.g., due to browser security restrictions or lack of user gesture). Failing to await can lead to unhandled promise rejections.
- gotcha The default import in the README uses `@vue/composition-api` for `defineComponent` and `ref`. For modern Vue 3 projects (Vue 3.0+), these should be imported directly from 'vue'.
Install
-
npm install vue-clipboard3 -
yarn add vue-clipboard3 -
pnpm add vue-clipboard3
Imports
- useClipboard
import { useClipboard } from 'vue-clipboard3'import useClipboard from 'vue-clipboard3'
- Options
import { Options } from 'vue-clipboard3'import type { Options } from 'vue-clipboard3' - CommonJS require
const useClipboard = require('vue-clipboard3')N/A
Quickstart
import { defineComponent, ref } from 'vue';
import useClipboard from 'vue-clipboard3';
export default defineComponent({
setup() {
const { toClipboard } = useClipboard();
const inputText = ref('Hello, clipboard!');
const copyText = async (textToCopy: string) => {
try {
await toClipboard(textToCopy);
console.log(`'${textToCopy}' copied to clipboard successfully!`);
} catch (e) {
console.error('Failed to copy text:', e);
// Optionally, show a user-friendly error message
}
};
const copyInputContent = async () => {
await copyText(inputText.value);
}
return {
inputText,
copyText,
copyInputContent
};
},
template: `
<div style="font-family: sans-serif; max-width: 600px; margin: 20px auto; padding: 20px; border: 1px solid #eee; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
<h1 style="color: #333; font-size: 1.8em;">Vue-Clipboard3 Example</h1>
<p style="color: #555;">Click buttons to copy text to clipboard.</p>
<button @click="copyText('Simple text copy from a button')" style="background-color: #4CAF50; color: white; padding: 10px 15px; border: none; border-radius: 5px; cursor: pointer; font-size: 1em; margin-bottom: 20px;">Copy 'Simple text copy'</button>
<div style="margin-top: 15px; display: flex; align-items: center;">
<input type="text" v-model="inputText" placeholder="Enter text to copy" style="flex-grow: 1; padding: 10px; border: 1px solid #ccc; border-radius: 5px; font-size: 1em;">
<button @click="copyInputContent" style="margin-left: 10px; background-color: #008CBA; color: white; padding: 10px 15px; border: none; border-radius: 5px; cursor: pointer; font-size: 1em;">Copy Input Content</button>
</div>
<div style="margin-top: 25px; padding-top: 15px; border-top: 1px dashed #eee;">
<p style="color: #666; font-size: 0.9em;">This demonstrates using the <code>useClipboard</code> hook with both static strings and reactive refs. Check your browser's developer console for success or error messages after clicking the buttons.</p>
</div>
</div>
`
});