How to copy to clipboard in Vue 3
Copy any text to the clipboard in Vue 3 with the new Vue composition API.

Photo by Kelly on Unsplash

TL;DR: Use vue-clipboard3 (I maintain this package)

Today I needed to copy some text to the clipboard in my new Vue app where I’m using Vue 3 and the composition api.

I didn’t want to use a Vue directive as this seems a little messy and not so declarative, and the existing solutions either don’t work in Vue 3, don’t have good typescript support, are used as a Vue plugin binding to ‘this’ or are a hack of a Vue 2 solution.

So I set about writing a new composable that uses the trusted clipboard.js under the hood, is fully typed, is simple and has no side effects, is declarative and easy to use, and follows the spirit of Vue 3 and the composition API.

It turned out to be extremely easy to make! I just installed clipboard.js and it’s types:

$ yarn add clipboard

$ yarn add --dev @types/clipboard

And make a single composable file

// composables/useClipboard.ts import Clipboard from 'clipboard' interface Options {

/** Fixes IE by appending element to body */

appendToBody: boolean

} export default (opts?: Options) => {

// default appendToBody true

const appendToBody = opts?.appendToBody === undefined ? true : opts.appendToBody

return {

toClipboard(text: string, container?: HTMLElement) {

return new Promise((resolve, reject) => {

// make fake element

const fakeEl = document.createElement('button')

// setup a new Clipboard.js

const clipboard = new Clipboard(fakeEl, {

text: () => text,

action: () => 'copy',

container: container !== undefined ? container : document.body

})

clipboard.on('success', (e) => {

clipboard.destroy()

resolve(e)

})

clipboard.on('error', (e) => {

clipboard.destroy()

reject(e)

})

// appendToBody fixes IE

if (appendToBody) document.body.appendChild(fakeEl)

// simulate click

fakeEl.click()

// remove from body if appended

if (appendToBody) document.body.removeChild(fakeEl)

})

}

}

}

Then in my Vue component I use it like this (simplified version):

<template lang="html">

<button @click="copy">Copy!</button>

</template>



<script lang="ts">

import { defineComponent } from '@vue/composition-api'

import useClipboard from '~/composables/useClipboard'



export default defineComponent({

setup() {

const { toClipboard } = useClipboard()



const copy = async () => {

try {

await toClipboard('Any text you like')

console.log('Copied to clipboard')

} catch (e) {

console.error(e)

}

}



return { copy }

}

})

</script>

Made something useful? Open-source it!

I figured this may be useful to a lot of people as we transition from Vue 2 to Vue 3 and the composition API. So I open-sourced it!

Now you can simply:

$ yarn add vue-clipboard3

And

import useClipboard from 'vue-clipboard3'

Check out the repo and examples here:

And if you find any problems or have any feature requests, drop me an issue on the repo:

Happy clipboarding! 📋
['Jamie Curnow']
['NPM', 'Front End Development', 'Vuejs', 'Open Source', 'Clipboard']