この記事は、ラクスパートナーズ AdventCalendar 2025の5日目の記事です。
(個人で25日連続投稿にチャレンジ中のカレンダーになります)
Web APIのClipboard APIを使ってコピー&ペースト機能を実装する方法をまとめてみました。
(コードはVue.jsのComposition APIのものになります)
HTTPSでないとClipboard APIを利用できないことに注意が必要です(localhostは除きます)。
テキストのコピー&ペースト
まずは、よく見るテキストのコピー&ペースト機能です。
<script setup>
import { ref } from 'vue'
const text = ref('')
const onCopyText = () => navigator.clipboard.writeText(text.value)
const onPasteText = () => {
navigator.clipboard.readText().then((clipText) => {
text.value = clipText
})
}
</script>
<template>
<div>
<input type="text" v-model="text" />
<button type="button" @click="onCopyText">
コピー
</button>
<button type="button" @click="onPasteText">
ペースト
</button>
</div>
</template>
navigator.clipboard.writeText('コピーしたいテキスト')は、指定したテキストをクリップボードに書き込みます。
navigator.clipboard.readText()は、クリップボードにアクセスし、取得したデータをPromiseオブジェクトで返却します(そのため、thenやasync/awaitで受け取る必要あり)。
上記のコードでは、inputタグに入力したテキストをコピーしたり、逆にinputへコピーした内容をペーストしています。
readText()実行時に、クリップボードへのアクセス権限を許可を求めるポップアップが表示されます(clipboard-read権限の要求)。
こちらを拒否するとペーストすることができません。
画像のコピー&ペースト
画像などの任意のデータをコピー&ペーストすることもできます。
(ほぼMDNのサンプルコードの通りに書いただけですが、例は以下です)
<script setup>
import { ref } from 'vue'
import sampleImage from '@/assets/sample.png'
const imageUrl = sampleImage
const readImage = ref(null)
const onCopyImage = async () => {
try {
const blob = await fetch(imageUrl).then((res) => res.blob());
const item = new ClipboardItem({
[blob.type]: blob,
});
// クリップボードへ書き込む
await navigator.clipboard.write([item]);
} catch (e) {
console.error(e);
}
};
const onPasteImage = async () => {
try {
const items = await navigator.clipboard.read();
for (const item of items) {
for (const type of item.types) {
if (type.startsWith('image/')) {
const blob = await item.getType(type);
readImage.value = URL.createObjectURL(blob);
return;
}
}
}
} catch (e) {
console.error(e);
}
};
</script>
<template>
<div>
<div>
<button @click="onCopyImage">
画像をコピー
</button>
<button @click="onPasteImage">
画像をペースト
</button>
</div>
<br>
<div v-if="readImage">
<img :src="readImage" width="200" />
</div>
</div>
</template>
クリップボードへのデータの書き込みにはnavigator.clipboard.write()
クリップボードへのアクセスにはnavigator.clipboard.read()
を使用します。
コピーの処理の流れは以下です。
- fetchで画像を取得し、Blob(画像など様々なデータを扱えるオブジェクト)にする
- ClipboardItemオブジェクトを作成し、Blobにした画像データを渡す
-
navigator.clipboard.writeにClipboardItemオブジェクトを渡して、クリップボードに書き込み完了
ペーストの処理の流れは以下です。
- navigator.clipboard.read()でクリップボードにアクセス
- typeが「image/」で始まるものを探す
- ClipboardオブジェクトのgetType()メソッドでBlobオブジェクトを返す
- 受け取ったBlobオブジェクトを元に、URL.createObjectURLで画像URLを生成
- 生成した画像URLをimgタグのsrc属性に指定し、画像が表示される
read()実行時も、clipboard-read権限を要求するポップアップが表示されます。
こちらも拒否した場合はペーストできません。
以上となります。
テキストのコピー&ペーストはよく実装していたのですが、画像などのデータのコピー&ペーストもClipboard APIで実装できるとは知らず、勉強になりました。是非業務でも活かしていきたいと思います。
ここまで読んでくださり、ありがとうございました。